diff options
Diffstat (limited to 'lib/rbcodec/codecs/libopus/silk')
166 files changed, 22320 insertions, 421 deletions
diff --git a/lib/rbcodec/codecs/libopus/silk/A2NLSF.c b/lib/rbcodec/codecs/libopus/silk/A2NLSF.c new file mode 100644 index 0000000000..b487686ff9 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/A2NLSF.c | |||
@@ -0,0 +1,267 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | /* Conversion between prediction filter coefficients and NLSFs */ | ||
29 | /* Requires the order to be an even number */ | ||
30 | /* A piecewise linear approximation maps LSF <-> cos(LSF) */ | ||
31 | /* Therefore the result is not accurate NLSFs, but the two */ | ||
32 | /* functions are accurate inverses of each other */ | ||
33 | |||
34 | #ifdef HAVE_CONFIG_H | ||
35 | #include "config.h" | ||
36 | #endif | ||
37 | |||
38 | #include "SigProc_FIX.h" | ||
39 | #include "tables.h" | ||
40 | |||
41 | /* Number of binary divisions, when not in low complexity mode */ | ||
42 | #define BIN_DIV_STEPS_A2NLSF_FIX 3 /* must be no higher than 16 - log2( LSF_COS_TAB_SZ_FIX ) */ | ||
43 | #define MAX_ITERATIONS_A2NLSF_FIX 16 | ||
44 | |||
45 | /* Helper function for A2NLSF(..) */ | ||
46 | /* Transforms polynomials from cos(n*f) to cos(f)^n */ | ||
47 | static OPUS_INLINE void silk_A2NLSF_trans_poly( | ||
48 | opus_int32 *p, /* I/O Polynomial */ | ||
49 | const opus_int dd /* I Polynomial order (= filter order / 2 ) */ | ||
50 | ) | ||
51 | { | ||
52 | opus_int k, n; | ||
53 | |||
54 | for( k = 2; k <= dd; k++ ) { | ||
55 | for( n = dd; n > k; n-- ) { | ||
56 | p[ n - 2 ] -= p[ n ]; | ||
57 | } | ||
58 | p[ k - 2 ] -= silk_LSHIFT( p[ k ], 1 ); | ||
59 | } | ||
60 | } | ||
61 | /* Helper function for A2NLSF(..) */ | ||
62 | /* Polynomial evaluation */ | ||
63 | static OPUS_INLINE opus_int32 silk_A2NLSF_eval_poly( /* return the polynomial evaluation, in Q16 */ | ||
64 | opus_int32 *p, /* I Polynomial, Q16 */ | ||
65 | const opus_int32 x, /* I Evaluation point, Q12 */ | ||
66 | const opus_int dd /* I Order */ | ||
67 | ) | ||
68 | { | ||
69 | opus_int n; | ||
70 | opus_int32 x_Q16, y32; | ||
71 | |||
72 | y32 = p[ dd ]; /* Q16 */ | ||
73 | x_Q16 = silk_LSHIFT( x, 4 ); | ||
74 | |||
75 | if ( opus_likely( 8 == dd ) ) | ||
76 | { | ||
77 | y32 = silk_SMLAWW( p[ 7 ], y32, x_Q16 ); | ||
78 | y32 = silk_SMLAWW( p[ 6 ], y32, x_Q16 ); | ||
79 | y32 = silk_SMLAWW( p[ 5 ], y32, x_Q16 ); | ||
80 | y32 = silk_SMLAWW( p[ 4 ], y32, x_Q16 ); | ||
81 | y32 = silk_SMLAWW( p[ 3 ], y32, x_Q16 ); | ||
82 | y32 = silk_SMLAWW( p[ 2 ], y32, x_Q16 ); | ||
83 | y32 = silk_SMLAWW( p[ 1 ], y32, x_Q16 ); | ||
84 | y32 = silk_SMLAWW( p[ 0 ], y32, x_Q16 ); | ||
85 | } | ||
86 | else | ||
87 | { | ||
88 | for( n = dd - 1; n >= 0; n-- ) { | ||
89 | y32 = silk_SMLAWW( p[ n ], y32, x_Q16 ); /* Q16 */ | ||
90 | } | ||
91 | } | ||
92 | return y32; | ||
93 | } | ||
94 | |||
95 | static OPUS_INLINE void silk_A2NLSF_init( | ||
96 | const opus_int32 *a_Q16, | ||
97 | opus_int32 *P, | ||
98 | opus_int32 *Q, | ||
99 | const opus_int dd | ||
100 | ) | ||
101 | { | ||
102 | opus_int k; | ||
103 | |||
104 | /* Convert filter coefs to even and odd polynomials */ | ||
105 | P[dd] = silk_LSHIFT( 1, 16 ); | ||
106 | Q[dd] = silk_LSHIFT( 1, 16 ); | ||
107 | for( k = 0; k < dd; k++ ) { | ||
108 | P[ k ] = -a_Q16[ dd - k - 1 ] - a_Q16[ dd + k ]; /* Q16 */ | ||
109 | Q[ k ] = -a_Q16[ dd - k - 1 ] + a_Q16[ dd + k ]; /* Q16 */ | ||
110 | } | ||
111 | |||
112 | /* Divide out zeros as we have that for even filter orders, */ | ||
113 | /* z = 1 is always a root in Q, and */ | ||
114 | /* z = -1 is always a root in P */ | ||
115 | for( k = dd; k > 0; k-- ) { | ||
116 | P[ k - 1 ] -= P[ k ]; | ||
117 | Q[ k - 1 ] += Q[ k ]; | ||
118 | } | ||
119 | |||
120 | /* Transform polynomials from cos(n*f) to cos(f)^n */ | ||
121 | silk_A2NLSF_trans_poly( P, dd ); | ||
122 | silk_A2NLSF_trans_poly( Q, dd ); | ||
123 | } | ||
124 | |||
125 | /* Compute Normalized Line Spectral Frequencies (NLSFs) from whitening filter coefficients */ | ||
126 | /* If not all roots are found, the a_Q16 coefficients are bandwidth expanded until convergence. */ | ||
127 | void silk_A2NLSF( | ||
128 | opus_int16 *NLSF, /* O Normalized Line Spectral Frequencies in Q15 (0..2^15-1) [d] */ | ||
129 | opus_int32 *a_Q16, /* I/O Monic whitening filter coefficients in Q16 [d] */ | ||
130 | const opus_int d /* I Filter order (must be even) */ | ||
131 | ) | ||
132 | { | ||
133 | opus_int i, k, m, dd, root_ix, ffrac; | ||
134 | opus_int32 xlo, xhi, xmid; | ||
135 | opus_int32 ylo, yhi, ymid, thr; | ||
136 | opus_int32 nom, den; | ||
137 | opus_int32 P[ SILK_MAX_ORDER_LPC / 2 + 1 ]; | ||
138 | opus_int32 Q[ SILK_MAX_ORDER_LPC / 2 + 1 ]; | ||
139 | opus_int32 *PQ[ 2 ]; | ||
140 | opus_int32 *p; | ||
141 | |||
142 | /* Store pointers to array */ | ||
143 | PQ[ 0 ] = P; | ||
144 | PQ[ 1 ] = Q; | ||
145 | |||
146 | dd = silk_RSHIFT( d, 1 ); | ||
147 | |||
148 | silk_A2NLSF_init( a_Q16, P, Q, dd ); | ||
149 | |||
150 | /* Find roots, alternating between P and Q */ | ||
151 | p = P; /* Pointer to polynomial */ | ||
152 | |||
153 | xlo = silk_LSFCosTab_FIX_Q12[ 0 ]; /* Q12*/ | ||
154 | ylo = silk_A2NLSF_eval_poly( p, xlo, dd ); | ||
155 | |||
156 | if( ylo < 0 ) { | ||
157 | /* Set the first NLSF to zero and move on to the next */ | ||
158 | NLSF[ 0 ] = 0; | ||
159 | p = Q; /* Pointer to polynomial */ | ||
160 | ylo = silk_A2NLSF_eval_poly( p, xlo, dd ); | ||
161 | root_ix = 1; /* Index of current root */ | ||
162 | } else { | ||
163 | root_ix = 0; /* Index of current root */ | ||
164 | } | ||
165 | k = 1; /* Loop counter */ | ||
166 | i = 0; /* Counter for bandwidth expansions applied */ | ||
167 | thr = 0; | ||
168 | while( 1 ) { | ||
169 | /* Evaluate polynomial */ | ||
170 | xhi = silk_LSFCosTab_FIX_Q12[ k ]; /* Q12 */ | ||
171 | yhi = silk_A2NLSF_eval_poly( p, xhi, dd ); | ||
172 | |||
173 | /* Detect zero crossing */ | ||
174 | if( ( ylo <= 0 && yhi >= thr ) || ( ylo >= 0 && yhi <= -thr ) ) { | ||
175 | if( yhi == 0 ) { | ||
176 | /* If the root lies exactly at the end of the current */ | ||
177 | /* interval, look for the next root in the next interval */ | ||
178 | thr = 1; | ||
179 | } else { | ||
180 | thr = 0; | ||
181 | } | ||
182 | /* Binary division */ | ||
183 | ffrac = -256; | ||
184 | for( m = 0; m < BIN_DIV_STEPS_A2NLSF_FIX; m++ ) { | ||
185 | /* Evaluate polynomial */ | ||
186 | xmid = silk_RSHIFT_ROUND( xlo + xhi, 1 ); | ||
187 | ymid = silk_A2NLSF_eval_poly( p, xmid, dd ); | ||
188 | |||
189 | /* Detect zero crossing */ | ||
190 | if( ( ylo <= 0 && ymid >= 0 ) || ( ylo >= 0 && ymid <= 0 ) ) { | ||
191 | /* Reduce frequency */ | ||
192 | xhi = xmid; | ||
193 | yhi = ymid; | ||
194 | } else { | ||
195 | /* Increase frequency */ | ||
196 | xlo = xmid; | ||
197 | ylo = ymid; | ||
198 | ffrac = silk_ADD_RSHIFT( ffrac, 128, m ); | ||
199 | } | ||
200 | } | ||
201 | |||
202 | /* Interpolate */ | ||
203 | if( silk_abs( ylo ) < 65536 ) { | ||
204 | /* Avoid dividing by zero */ | ||
205 | den = ylo - yhi; | ||
206 | nom = silk_LSHIFT( ylo, 8 - BIN_DIV_STEPS_A2NLSF_FIX ) + silk_RSHIFT( den, 1 ); | ||
207 | if( den != 0 ) { | ||
208 | ffrac += silk_DIV32( nom, den ); | ||
209 | } | ||
210 | } else { | ||
211 | /* No risk of dividing by zero because abs(ylo - yhi) >= abs(ylo) >= 65536 */ | ||
212 | ffrac += silk_DIV32( ylo, silk_RSHIFT( ylo - yhi, 8 - BIN_DIV_STEPS_A2NLSF_FIX ) ); | ||
213 | } | ||
214 | NLSF[ root_ix ] = (opus_int16)silk_min_32( silk_LSHIFT( (opus_int32)k, 8 ) + ffrac, silk_int16_MAX ); | ||
215 | |||
216 | silk_assert( NLSF[ root_ix ] >= 0 ); | ||
217 | |||
218 | root_ix++; /* Next root */ | ||
219 | if( root_ix >= d ) { | ||
220 | /* Found all roots */ | ||
221 | break; | ||
222 | } | ||
223 | /* Alternate pointer to polynomial */ | ||
224 | p = PQ[ root_ix & 1 ]; | ||
225 | |||
226 | /* Evaluate polynomial */ | ||
227 | xlo = silk_LSFCosTab_FIX_Q12[ k - 1 ]; /* Q12*/ | ||
228 | ylo = silk_LSHIFT( 1 - ( root_ix & 2 ), 12 ); | ||
229 | } else { | ||
230 | /* Increment loop counter */ | ||
231 | k++; | ||
232 | xlo = xhi; | ||
233 | ylo = yhi; | ||
234 | thr = 0; | ||
235 | |||
236 | if( k > LSF_COS_TAB_SZ_FIX ) { | ||
237 | i++; | ||
238 | if( i > MAX_ITERATIONS_A2NLSF_FIX ) { | ||
239 | /* Set NLSFs to white spectrum and exit */ | ||
240 | NLSF[ 0 ] = (opus_int16)silk_DIV32_16( 1 << 15, d + 1 ); | ||
241 | for( k = 1; k < d; k++ ) { | ||
242 | NLSF[ k ] = (opus_int16)silk_ADD16( NLSF[ k-1 ], NLSF[ 0 ] ); | ||
243 | } | ||
244 | return; | ||
245 | } | ||
246 | |||
247 | /* Error: Apply progressively more bandwidth expansion and run again */ | ||
248 | silk_bwexpander_32( a_Q16, d, 65536 - silk_LSHIFT( 1, i ) ); | ||
249 | |||
250 | silk_A2NLSF_init( a_Q16, P, Q, dd ); | ||
251 | p = P; /* Pointer to polynomial */ | ||
252 | xlo = silk_LSFCosTab_FIX_Q12[ 0 ]; /* Q12*/ | ||
253 | ylo = silk_A2NLSF_eval_poly( p, xlo, dd ); | ||
254 | if( ylo < 0 ) { | ||
255 | /* Set the first NLSF to zero and move on to the next */ | ||
256 | NLSF[ 0 ] = 0; | ||
257 | p = Q; /* Pointer to polynomial */ | ||
258 | ylo = silk_A2NLSF_eval_poly( p, xlo, dd ); | ||
259 | root_ix = 1; /* Index of current root */ | ||
260 | } else { | ||
261 | root_ix = 0; /* Index of current root */ | ||
262 | } | ||
263 | k = 1; /* Reset loop counter */ | ||
264 | } | ||
265 | } | ||
266 | } | ||
267 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/API.h b/lib/rbcodec/codecs/libopus/silk/API.h index f0601bcf6b..4d90ff9aa3 100644 --- a/lib/rbcodec/codecs/libopus/silk/API.h +++ b/lib/rbcodec/codecs/libopus/silk/API.h | |||
@@ -80,7 +80,8 @@ opus_int silk_Encode( /* O Returns error co | |||
80 | opus_int nSamplesIn, /* I Number of samples in input vector */ | 80 | opus_int nSamplesIn, /* I Number of samples in input vector */ |
81 | ec_enc *psRangeEnc, /* I/O Compressor data structure */ | 81 | ec_enc *psRangeEnc, /* I/O Compressor data structure */ |
82 | opus_int32 *nBytesOut, /* I/O Number of bytes in payload (input: Max bytes) */ | 82 | opus_int32 *nBytesOut, /* I/O Number of bytes in payload (input: Max bytes) */ |
83 | const opus_int prefillFlag /* I Flag to indicate prefilling buffers no coding */ | 83 | const opus_int prefillFlag, /* I Flag to indicate prefilling buffers no coding */ |
84 | int activity /* I Decision of Opus voice activity detector */ | ||
84 | ); | 85 | ); |
85 | 86 | ||
86 | /****************************************/ | 87 | /****************************************/ |
@@ -111,7 +112,8 @@ opus_int silk_Decode( /* O Returns error co | |||
111 | opus_int newPacketFlag, /* I Indicates first decoder call for this packet */ | 112 | opus_int newPacketFlag, /* I Indicates first decoder call for this packet */ |
112 | ec_dec *psRangeDec, /* I/O Compressor data structure */ | 113 | ec_dec *psRangeDec, /* I/O Compressor data structure */ |
113 | opus_int16 *samplesOut, /* O Decoded output speech vector */ | 114 | opus_int16 *samplesOut, /* O Decoded output speech vector */ |
114 | opus_int32 *nSamplesOut /* O Number of samples decoded */ | 115 | opus_int32 *nSamplesOut, /* O Number of samples decoded */ |
116 | int arch /* I Run-time architecture */ | ||
115 | ); | 117 | ); |
116 | 118 | ||
117 | #if 0 | 119 | #if 0 |
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 */ |
36 | static OPUS_INLINE void silk_CNG_exc( | 36 | static 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 | } |
diff --git a/lib/rbcodec/codecs/libopus/silk/HP_variable_cutoff.c b/lib/rbcodec/codecs/libopus/silk/HP_variable_cutoff.c new file mode 100644 index 0000000000..bbe10f04ce --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/HP_variable_cutoff.c | |||
@@ -0,0 +1,77 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | #ifdef FIXED_POINT | ||
32 | #include "main_FIX.h" | ||
33 | #else | ||
34 | #include "main_FLP.h" | ||
35 | #endif | ||
36 | #include "tuning_parameters.h" | ||
37 | |||
38 | /* High-pass filter with cutoff frequency adaptation based on pitch lag statistics */ | ||
39 | void silk_HP_variable_cutoff( | ||
40 | silk_encoder_state_Fxx state_Fxx[] /* I/O Encoder states */ | ||
41 | ) | ||
42 | { | ||
43 | opus_int quality_Q15; | ||
44 | opus_int32 pitch_freq_Hz_Q16, pitch_freq_log_Q7, delta_freq_Q7; | ||
45 | silk_encoder_state *psEncC1 = &state_Fxx[ 0 ].sCmn; | ||
46 | |||
47 | /* Adaptive cutoff frequency: estimate low end of pitch frequency range */ | ||
48 | if( psEncC1->prevSignalType == TYPE_VOICED ) { | ||
49 | /* difference, in log domain */ | ||
50 | pitch_freq_Hz_Q16 = silk_DIV32_16( silk_LSHIFT( silk_MUL( psEncC1->fs_kHz, 1000 ), 16 ), psEncC1->prevLag ); | ||
51 | pitch_freq_log_Q7 = silk_lin2log( pitch_freq_Hz_Q16 ) - ( 16 << 7 ); | ||
52 | |||
53 | /* adjustment based on quality */ | ||
54 | quality_Q15 = psEncC1->input_quality_bands_Q15[ 0 ]; | ||
55 | pitch_freq_log_Q7 = silk_SMLAWB( pitch_freq_log_Q7, silk_SMULWB( silk_LSHIFT( -quality_Q15, 2 ), quality_Q15 ), | ||
56 | pitch_freq_log_Q7 - ( silk_lin2log( SILK_FIX_CONST( VARIABLE_HP_MIN_CUTOFF_HZ, 16 ) ) - ( 16 << 7 ) ) ); | ||
57 | |||
58 | /* delta_freq = pitch_freq_log - psEnc->variable_HP_smth1; */ | ||
59 | delta_freq_Q7 = pitch_freq_log_Q7 - silk_RSHIFT( psEncC1->variable_HP_smth1_Q15, 8 ); | ||
60 | if( delta_freq_Q7 < 0 ) { | ||
61 | /* less smoothing for decreasing pitch frequency, to track something close to the minimum */ | ||
62 | delta_freq_Q7 = silk_MUL( delta_freq_Q7, 3 ); | ||
63 | } | ||
64 | |||
65 | /* limit delta, to reduce impact of outliers in pitch estimation */ | ||
66 | delta_freq_Q7 = silk_LIMIT_32( delta_freq_Q7, -SILK_FIX_CONST( VARIABLE_HP_MAX_DELTA_FREQ, 7 ), SILK_FIX_CONST( VARIABLE_HP_MAX_DELTA_FREQ, 7 ) ); | ||
67 | |||
68 | /* update smoother */ | ||
69 | psEncC1->variable_HP_smth1_Q15 = silk_SMLAWB( psEncC1->variable_HP_smth1_Q15, | ||
70 | silk_SMULBB( psEncC1->speech_activity_Q8, delta_freq_Q7 ), SILK_FIX_CONST( VARIABLE_HP_SMTH_COEF1, 16 ) ); | ||
71 | |||
72 | /* limit frequency range */ | ||
73 | psEncC1->variable_HP_smth1_Q15 = silk_LIMIT_32( psEncC1->variable_HP_smth1_Q15, | ||
74 | silk_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 ), | ||
75 | silk_LSHIFT( silk_lin2log( VARIABLE_HP_MAX_CUTOFF_HZ ), 8 ) ); | ||
76 | } | ||
77 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/LPC_analysis_filter.c b/lib/rbcodec/codecs/libopus/silk/LPC_analysis_filter.c index 9d1f16cb7d..d34b5eb709 100644 --- a/lib/rbcodec/codecs/libopus/silk/LPC_analysis_filter.c +++ b/lib/rbcodec/codecs/libopus/silk/LPC_analysis_filter.c | |||
@@ -39,17 +39,24 @@ POSSIBILITY OF SUCH DAMAGE. | |||
39 | /* first d output samples are set to zero */ | 39 | /* first d output samples are set to zero */ |
40 | /*******************************************/ | 40 | /*******************************************/ |
41 | 41 | ||
42 | /* OPT: Using celt_fir() for this function should be faster, but it may cause | ||
43 | integer overflows in intermediate values (not final results), which the | ||
44 | current implementation silences by casting to unsigned. Enabling | ||
45 | this should be safe in pretty much all cases, even though it is not technically | ||
46 | C89-compliant. */ | ||
47 | #define USE_CELT_FIR 0 | ||
48 | |||
42 | void silk_LPC_analysis_filter( | 49 | void silk_LPC_analysis_filter( |
43 | opus_int16 *out, /* O Output signal */ | 50 | opus_int16 *out, /* O Output signal */ |
44 | const opus_int16 *in, /* I Input signal */ | 51 | const opus_int16 *in, /* I Input signal */ |
45 | const opus_int16 *B, /* I MA prediction coefficients, Q12 [order] */ | 52 | const opus_int16 *B, /* I MA prediction coefficients, Q12 [order] */ |
46 | const opus_int32 len, /* I Signal length */ | 53 | const opus_int32 len, /* I Signal length */ |
47 | const opus_int32 d /* I Filter order */ | 54 | const opus_int32 d, /* I Filter order */ |
55 | int arch /* I Run-time architecture */ | ||
48 | ) | 56 | ) |
49 | { | 57 | { |
50 | opus_int j; | 58 | opus_int j; |
51 | #ifdef FIXED_POINT | 59 | #if defined(FIXED_POINT) && USE_CELT_FIR |
52 | opus_int16 mem[SILK_MAX_ORDER_LPC]; | ||
53 | opus_int16 num[SILK_MAX_ORDER_LPC]; | 60 | opus_int16 num[SILK_MAX_ORDER_LPC]; |
54 | #else | 61 | #else |
55 | int ix; | 62 | int ix; |
@@ -57,23 +64,21 @@ void silk_LPC_analysis_filter( | |||
57 | const opus_int16 *in_ptr; | 64 | const opus_int16 *in_ptr; |
58 | #endif | 65 | #endif |
59 | 66 | ||
60 | silk_assert( d >= 6 ); | 67 | celt_assert( d >= 6 ); |
61 | silk_assert( (d & 1) == 0 ); | 68 | celt_assert( (d & 1) == 0 ); |
62 | silk_assert( d <= len ); | 69 | celt_assert( d <= len ); |
63 | 70 | ||
64 | #ifdef FIXED_POINT | 71 | #if defined(FIXED_POINT) && USE_CELT_FIR |
65 | silk_assert( d <= SILK_MAX_ORDER_LPC ); | 72 | celt_assert( d <= SILK_MAX_ORDER_LPC ); |
66 | for ( j = 0; j < d; j++ ) { | 73 | for ( j = 0; j < d; j++ ) { |
67 | num[ j ] = -B[ j ]; | 74 | num[ j ] = -B[ j ]; |
68 | } | 75 | } |
69 | for (j=0;j<d;j++) { | 76 | celt_fir( in + d, num, out + d, len - d, d, arch ); |
70 | mem[ j ] = in[ d - j - 1 ]; | ||
71 | } | ||
72 | celt_fir( in + d, num, out + d, len - d, d, mem ); | ||
73 | for ( j = 0; j < d; j++ ) { | 77 | for ( j = 0; j < d; j++ ) { |
74 | out[ j ] = 0; | 78 | out[ j ] = 0; |
75 | } | 79 | } |
76 | #else | 80 | #else |
81 | (void)arch; | ||
77 | for( ix = d; ix < len; ix++ ) { | 82 | for( ix = d; ix < len; ix++ ) { |
78 | in_ptr = &in[ ix - 1 ]; | 83 | in_ptr = &in[ ix - 1 ]; |
79 | 84 | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/LPC_fit.c b/lib/rbcodec/codecs/libopus/silk/LPC_fit.c new file mode 100644 index 0000000000..cdea4f3abc --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/LPC_fit.c | |||
@@ -0,0 +1,81 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2013, Koen Vos. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "SigProc_FIX.h" | ||
33 | |||
34 | /* Convert int32 coefficients to int16 coefs and make sure there's no wrap-around */ | ||
35 | void silk_LPC_fit( | ||
36 | opus_int16 *a_QOUT, /* O Output signal */ | ||
37 | opus_int32 *a_QIN, /* I/O Input signal */ | ||
38 | const opus_int QOUT, /* I Input Q domain */ | ||
39 | const opus_int QIN, /* I Input Q domain */ | ||
40 | const opus_int d /* I Filter order */ | ||
41 | ) | ||
42 | { | ||
43 | opus_int i, k, idx = 0; | ||
44 | opus_int32 maxabs, absval, chirp_Q16; | ||
45 | |||
46 | /* Limit the maximum absolute value of the prediction coefficients, so that they'll fit in int16 */ | ||
47 | for( i = 0; i < 10; i++ ) { | ||
48 | /* Find maximum absolute value and its index */ | ||
49 | maxabs = 0; | ||
50 | for( k = 0; k < d; k++ ) { | ||
51 | absval = silk_abs( a_QIN[k] ); | ||
52 | if( absval > maxabs ) { | ||
53 | maxabs = absval; | ||
54 | idx = k; | ||
55 | } | ||
56 | } | ||
57 | maxabs = silk_RSHIFT_ROUND( maxabs, QIN - QOUT ); | ||
58 | |||
59 | if( maxabs > silk_int16_MAX ) { | ||
60 | /* Reduce magnitude of prediction coefficients */ | ||
61 | maxabs = silk_min( maxabs, 163838 ); /* ( silk_int32_MAX >> 14 ) + silk_int16_MAX = 163838 */ | ||
62 | chirp_Q16 = SILK_FIX_CONST( 0.999, 16 ) - silk_DIV32( silk_LSHIFT( maxabs - silk_int16_MAX, 14 ), | ||
63 | silk_RSHIFT32( silk_MUL( maxabs, idx + 1), 2 ) ); | ||
64 | silk_bwexpander_32( a_QIN, d, chirp_Q16 ); | ||
65 | } else { | ||
66 | break; | ||
67 | } | ||
68 | } | ||
69 | |||
70 | if( i == 10 ) { | ||
71 | /* Reached the last iteration, clip the coefficients */ | ||
72 | for( k = 0; k < d; k++ ) { | ||
73 | a_QOUT[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( a_QIN[ k ], QIN - QOUT ) ); | ||
74 | a_QIN[ k ] = silk_LSHIFT( (opus_int32)a_QOUT[ k ], QIN - QOUT ); | ||
75 | } | ||
76 | } else { | ||
77 | for( k = 0; k < d; k++ ) { | ||
78 | a_QOUT[ k ] = (opus_int16)silk_RSHIFT_ROUND( a_QIN[ k ], QIN - QOUT ); | ||
79 | } | ||
80 | } | ||
81 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/LPC_inv_pred_gain.c b/lib/rbcodec/codecs/libopus/silk/LPC_inv_pred_gain.c index dd14d4bca6..a3746a6ef9 100644 --- a/lib/rbcodec/codecs/libopus/silk/LPC_inv_pred_gain.c +++ b/lib/rbcodec/codecs/libopus/silk/LPC_inv_pred_gain.c | |||
@@ -30,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. | |||
30 | #endif | 30 | #endif |
31 | 31 | ||
32 | #include "SigProc_FIX.h" | 32 | #include "SigProc_FIX.h" |
33 | #include "define.h" | ||
33 | 34 | ||
34 | #define QA 24 | 35 | #define QA 24 |
35 | #define A_LIMIT SILK_FIX_CONST( 0.99975, QA ) | 36 | #define A_LIMIT SILK_FIX_CONST( 0.99975, QA ) |
@@ -38,119 +39,103 @@ POSSIBILITY OF SUCH DAMAGE. | |||
38 | 39 | ||
39 | /* Compute inverse of LPC prediction gain, and */ | 40 | /* Compute inverse of LPC prediction gain, and */ |
40 | /* test if LPC coefficients are stable (all poles within unit circle) */ | 41 | /* test if LPC coefficients are stable (all poles within unit circle) */ |
41 | static opus_int32 LPC_inverse_pred_gain_QA( /* O Returns inverse prediction gain in energy domain, Q30 */ | 42 | static opus_int32 LPC_inverse_pred_gain_QA_c( /* O Returns inverse prediction gain in energy domain, Q30 */ |
42 | opus_int32 A_QA[ 2 ][ SILK_MAX_ORDER_LPC ], /* I Prediction coefficients */ | 43 | opus_int32 A_QA[ SILK_MAX_ORDER_LPC ], /* I Prediction coefficients */ |
43 | const opus_int order /* I Prediction order */ | 44 | const opus_int order /* I Prediction order */ |
44 | ) | 45 | ) |
45 | { | 46 | { |
46 | opus_int k, n, mult2Q; | 47 | opus_int k, n, mult2Q; |
47 | opus_int32 invGain_Q30, rc_Q31, rc_mult1_Q30, rc_mult2, tmp_QA; | 48 | opus_int32 invGain_Q30, rc_Q31, rc_mult1_Q30, rc_mult2, tmp1, tmp2; |
48 | opus_int32 *Aold_QA, *Anew_QA; | ||
49 | 49 | ||
50 | Anew_QA = A_QA[ order & 1 ]; | 50 | invGain_Q30 = SILK_FIX_CONST( 1, 30 ); |
51 | |||
52 | invGain_Q30 = (opus_int32)1 << 30; | ||
53 | for( k = order - 1; k > 0; k-- ) { | 51 | for( k = order - 1; k > 0; k-- ) { |
54 | /* Check for stability */ | 52 | /* Check for stability */ |
55 | if( ( Anew_QA[ k ] > A_LIMIT ) || ( Anew_QA[ k ] < -A_LIMIT ) ) { | 53 | if( ( A_QA[ k ] > A_LIMIT ) || ( A_QA[ k ] < -A_LIMIT ) ) { |
56 | return 0; | 54 | return 0; |
57 | } | 55 | } |
58 | 56 | ||
59 | /* Set RC equal to negated AR coef */ | 57 | /* Set RC equal to negated AR coef */ |
60 | rc_Q31 = -silk_LSHIFT( Anew_QA[ k ], 31 - QA ); | 58 | rc_Q31 = -silk_LSHIFT( A_QA[ k ], 31 - QA ); |
61 | 59 | ||
62 | /* rc_mult1_Q30 range: [ 1 : 2^30 ] */ | 60 | /* rc_mult1_Q30 range: [ 1 : 2^30 ] */ |
63 | rc_mult1_Q30 = ( (opus_int32)1 << 30 ) - silk_SMMUL( rc_Q31, rc_Q31 ); | 61 | rc_mult1_Q30 = silk_SUB32( SILK_FIX_CONST( 1, 30 ), silk_SMMUL( rc_Q31, rc_Q31 ) ); |
64 | silk_assert( rc_mult1_Q30 > ( 1 << 15 ) ); /* reduce A_LIMIT if fails */ | 62 | silk_assert( rc_mult1_Q30 > ( 1 << 15 ) ); /* reduce A_LIMIT if fails */ |
65 | silk_assert( rc_mult1_Q30 <= ( 1 << 30 ) ); | 63 | silk_assert( rc_mult1_Q30 <= ( 1 << 30 ) ); |
66 | 64 | ||
67 | /* rc_mult2 range: [ 2^30 : silk_int32_MAX ] */ | ||
68 | mult2Q = 32 - silk_CLZ32( silk_abs( rc_mult1_Q30 ) ); | ||
69 | rc_mult2 = silk_INVERSE32_varQ( rc_mult1_Q30, mult2Q + 30 ); | ||
70 | |||
71 | /* Update inverse gain */ | 65 | /* Update inverse gain */ |
72 | /* invGain_Q30 range: [ 0 : 2^30 ] */ | 66 | /* invGain_Q30 range: [ 0 : 2^30 ] */ |
73 | invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 ); | 67 | invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 ); |
74 | silk_assert( invGain_Q30 >= 0 ); | 68 | silk_assert( invGain_Q30 >= 0 ); |
75 | silk_assert( invGain_Q30 <= ( 1 << 30 ) ); | 69 | silk_assert( invGain_Q30 <= ( 1 << 30 ) ); |
70 | if( invGain_Q30 < SILK_FIX_CONST( 1.0f / MAX_PREDICTION_POWER_GAIN, 30 ) ) { | ||
71 | return 0; | ||
72 | } | ||
76 | 73 | ||
77 | /* Swap pointers */ | 74 | /* rc_mult2 range: [ 2^30 : silk_int32_MAX ] */ |
78 | Aold_QA = Anew_QA; | 75 | mult2Q = 32 - silk_CLZ32( silk_abs( rc_mult1_Q30 ) ); |
79 | Anew_QA = A_QA[ k & 1 ]; | 76 | rc_mult2 = silk_INVERSE32_varQ( rc_mult1_Q30, mult2Q + 30 ); |
80 | 77 | ||
81 | /* Update AR coefficient */ | 78 | /* Update AR coefficient */ |
82 | for( n = 0; n < k; n++ ) { | 79 | for( n = 0; n < (k + 1) >> 1; n++ ) { |
83 | tmp_QA = Aold_QA[ n ] - MUL32_FRAC_Q( Aold_QA[ k - n - 1 ], rc_Q31, 31 ); | 80 | opus_int64 tmp64; |
84 | Anew_QA[ n ] = MUL32_FRAC_Q( tmp_QA, rc_mult2 , mult2Q ); | 81 | tmp1 = A_QA[ n ]; |
82 | tmp2 = A_QA[ k - n - 1 ]; | ||
83 | tmp64 = silk_RSHIFT_ROUND64( silk_SMULL( silk_SUB_SAT32(tmp1, | ||
84 | MUL32_FRAC_Q( tmp2, rc_Q31, 31 ) ), rc_mult2 ), mult2Q); | ||
85 | if( tmp64 > silk_int32_MAX || tmp64 < silk_int32_MIN ) { | ||
86 | return 0; | ||
87 | } | ||
88 | A_QA[ n ] = ( opus_int32 )tmp64; | ||
89 | tmp64 = silk_RSHIFT_ROUND64( silk_SMULL( silk_SUB_SAT32(tmp2, | ||
90 | MUL32_FRAC_Q( tmp1, rc_Q31, 31 ) ), rc_mult2), mult2Q); | ||
91 | if( tmp64 > silk_int32_MAX || tmp64 < silk_int32_MIN ) { | ||
92 | return 0; | ||
93 | } | ||
94 | A_QA[ k - n - 1 ] = ( opus_int32 )tmp64; | ||
85 | } | 95 | } |
86 | } | 96 | } |
87 | 97 | ||
88 | /* Check for stability */ | 98 | /* Check for stability */ |
89 | if( ( Anew_QA[ 0 ] > A_LIMIT ) || ( Anew_QA[ 0 ] < -A_LIMIT ) ) { | 99 | if( ( A_QA[ k ] > A_LIMIT ) || ( A_QA[ k ] < -A_LIMIT ) ) { |
90 | return 0; | 100 | return 0; |
91 | } | 101 | } |
92 | 102 | ||
93 | /* Set RC equal to negated AR coef */ | 103 | /* Set RC equal to negated AR coef */ |
94 | rc_Q31 = -silk_LSHIFT( Anew_QA[ 0 ], 31 - QA ); | 104 | rc_Q31 = -silk_LSHIFT( A_QA[ 0 ], 31 - QA ); |
95 | 105 | ||
96 | /* Range: [ 1 : 2^30 ] */ | 106 | /* Range: [ 1 : 2^30 ] */ |
97 | rc_mult1_Q30 = ( (opus_int32)1 << 30 ) - silk_SMMUL( rc_Q31, rc_Q31 ); | 107 | rc_mult1_Q30 = silk_SUB32( SILK_FIX_CONST( 1, 30 ), silk_SMMUL( rc_Q31, rc_Q31 ) ); |
98 | 108 | ||
99 | /* Update inverse gain */ | 109 | /* Update inverse gain */ |
100 | /* Range: [ 0 : 2^30 ] */ | 110 | /* Range: [ 0 : 2^30 ] */ |
101 | invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 ); | 111 | invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 ); |
102 | silk_assert( invGain_Q30 >= 0 ); | 112 | silk_assert( invGain_Q30 >= 0 ); |
103 | silk_assert( invGain_Q30 <= 1<<30 ); | 113 | silk_assert( invGain_Q30 <= ( 1 << 30 ) ); |
114 | if( invGain_Q30 < SILK_FIX_CONST( 1.0f / MAX_PREDICTION_POWER_GAIN, 30 ) ) { | ||
115 | return 0; | ||
116 | } | ||
104 | 117 | ||
105 | return invGain_Q30; | 118 | return invGain_Q30; |
106 | } | 119 | } |
107 | 120 | ||
108 | /* For input in Q12 domain */ | 121 | /* For input in Q12 domain */ |
109 | opus_int32 silk_LPC_inverse_pred_gain( /* O Returns inverse prediction gain in energy domain, Q30 */ | 122 | opus_int32 silk_LPC_inverse_pred_gain_c( /* O Returns inverse prediction gain in energy domain, Q30 */ |
110 | const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */ | 123 | const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */ |
111 | const opus_int order /* I Prediction order */ | 124 | const opus_int order /* I Prediction order */ |
112 | ) | 125 | ) |
113 | { | 126 | { |
114 | opus_int k; | 127 | opus_int k; |
115 | opus_int32 Atmp_QA[ 2 ][ SILK_MAX_ORDER_LPC ]; | 128 | opus_int32 Atmp_QA[ SILK_MAX_ORDER_LPC ]; |
116 | opus_int32 *Anew_QA; | ||
117 | opus_int32 DC_resp = 0; | 129 | opus_int32 DC_resp = 0; |
118 | 130 | ||
119 | Anew_QA = Atmp_QA[ order & 1 ]; | ||
120 | |||
121 | /* Increase Q domain of the AR coefficients */ | 131 | /* Increase Q domain of the AR coefficients */ |
122 | for( k = 0; k < order; k++ ) { | 132 | for( k = 0; k < order; k++ ) { |
123 | DC_resp += (opus_int32)A_Q12[ k ]; | 133 | DC_resp += (opus_int32)A_Q12[ k ]; |
124 | Anew_QA[ k ] = silk_LSHIFT32( (opus_int32)A_Q12[ k ], QA - 12 ); | 134 | Atmp_QA[ k ] = silk_LSHIFT32( (opus_int32)A_Q12[ k ], QA - 12 ); |
125 | } | 135 | } |
126 | /* If the DC is unstable, we don't even need to do the full calculations */ | 136 | /* If the DC is unstable, we don't even need to do the full calculations */ |
127 | if( DC_resp >= 4096 ) { | 137 | if( DC_resp >= 4096 ) { |
128 | return 0; | 138 | return 0; |
129 | } | 139 | } |
130 | return LPC_inverse_pred_gain_QA( Atmp_QA, order ); | 140 | return LPC_inverse_pred_gain_QA_c( Atmp_QA, order ); |
131 | } | 141 | } |
132 | |||
133 | #ifdef FIXED_POINT | ||
134 | |||
135 | #if 0 | ||
136 | /* For input in Q24 domain */ | ||
137 | opus_int32 silk_LPC_inverse_pred_gain_Q24( /* O Returns inverse prediction gain in energy domain, Q30 */ | ||
138 | const opus_int32 *A_Q24, /* I Prediction coefficients [order] */ | ||
139 | const opus_int order /* I Prediction order */ | ||
140 | ) | ||
141 | { | ||
142 | opus_int k; | ||
143 | opus_int32 Atmp_QA[ 2 ][ SILK_MAX_ORDER_LPC ]; | ||
144 | opus_int32 *Anew_QA; | ||
145 | |||
146 | Anew_QA = Atmp_QA[ order & 1 ]; | ||
147 | |||
148 | /* Increase Q domain of the AR coefficients */ | ||
149 | for( k = 0; k < order; k++ ) { | ||
150 | Anew_QA[ k ] = silk_RSHIFT32( A_Q24[ k ], 24 - QA ); | ||
151 | } | ||
152 | |||
153 | return LPC_inverse_pred_gain_QA( Atmp_QA, order ); | ||
154 | } | ||
155 | #endif | ||
156 | #endif | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/LP_variable_cutoff.c b/lib/rbcodec/codecs/libopus/silk/LP_variable_cutoff.c new file mode 100644 index 0000000000..79112ad354 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/LP_variable_cutoff.c | |||
@@ -0,0 +1,135 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | /* | ||
33 | Elliptic/Cauer filters designed with 0.1 dB passband ripple, | ||
34 | 80 dB minimum stopband attenuation, and | ||
35 | [0.95 : 0.15 : 0.35] normalized cut off frequencies. | ||
36 | */ | ||
37 | |||
38 | #include "main.h" | ||
39 | |||
40 | /* Helper function, interpolates the filter taps */ | ||
41 | static OPUS_INLINE void silk_LP_interpolate_filter_taps( | ||
42 | opus_int32 B_Q28[ TRANSITION_NB ], | ||
43 | opus_int32 A_Q28[ TRANSITION_NA ], | ||
44 | const opus_int ind, | ||
45 | const opus_int32 fac_Q16 | ||
46 | ) | ||
47 | { | ||
48 | opus_int nb, na; | ||
49 | |||
50 | if( ind < TRANSITION_INT_NUM - 1 ) { | ||
51 | if( fac_Q16 > 0 ) { | ||
52 | if( fac_Q16 < 32768 ) { /* fac_Q16 is in range of a 16-bit int */ | ||
53 | /* Piece-wise linear interpolation of B and A */ | ||
54 | for( nb = 0; nb < TRANSITION_NB; nb++ ) { | ||
55 | B_Q28[ nb ] = silk_SMLAWB( | ||
56 | silk_Transition_LP_B_Q28[ ind ][ nb ], | ||
57 | silk_Transition_LP_B_Q28[ ind + 1 ][ nb ] - | ||
58 | silk_Transition_LP_B_Q28[ ind ][ nb ], | ||
59 | fac_Q16 ); | ||
60 | } | ||
61 | for( na = 0; na < TRANSITION_NA; na++ ) { | ||
62 | A_Q28[ na ] = silk_SMLAWB( | ||
63 | silk_Transition_LP_A_Q28[ ind ][ na ], | ||
64 | silk_Transition_LP_A_Q28[ ind + 1 ][ na ] - | ||
65 | silk_Transition_LP_A_Q28[ ind ][ na ], | ||
66 | fac_Q16 ); | ||
67 | } | ||
68 | } else { /* ( fac_Q16 - ( 1 << 16 ) ) is in range of a 16-bit int */ | ||
69 | silk_assert( fac_Q16 - ( 1 << 16 ) == silk_SAT16( fac_Q16 - ( 1 << 16 ) ) ); | ||
70 | /* Piece-wise linear interpolation of B and A */ | ||
71 | for( nb = 0; nb < TRANSITION_NB; nb++ ) { | ||
72 | B_Q28[ nb ] = silk_SMLAWB( | ||
73 | silk_Transition_LP_B_Q28[ ind + 1 ][ nb ], | ||
74 | silk_Transition_LP_B_Q28[ ind + 1 ][ nb ] - | ||
75 | silk_Transition_LP_B_Q28[ ind ][ nb ], | ||
76 | fac_Q16 - ( (opus_int32)1 << 16 ) ); | ||
77 | } | ||
78 | for( na = 0; na < TRANSITION_NA; na++ ) { | ||
79 | A_Q28[ na ] = silk_SMLAWB( | ||
80 | silk_Transition_LP_A_Q28[ ind + 1 ][ na ], | ||
81 | silk_Transition_LP_A_Q28[ ind + 1 ][ na ] - | ||
82 | silk_Transition_LP_A_Q28[ ind ][ na ], | ||
83 | fac_Q16 - ( (opus_int32)1 << 16 ) ); | ||
84 | } | ||
85 | } | ||
86 | } else { | ||
87 | silk_memcpy( B_Q28, silk_Transition_LP_B_Q28[ ind ], TRANSITION_NB * sizeof( opus_int32 ) ); | ||
88 | silk_memcpy( A_Q28, silk_Transition_LP_A_Q28[ ind ], TRANSITION_NA * sizeof( opus_int32 ) ); | ||
89 | } | ||
90 | } else { | ||
91 | silk_memcpy( B_Q28, silk_Transition_LP_B_Q28[ TRANSITION_INT_NUM - 1 ], TRANSITION_NB * sizeof( opus_int32 ) ); | ||
92 | silk_memcpy( A_Q28, silk_Transition_LP_A_Q28[ TRANSITION_INT_NUM - 1 ], TRANSITION_NA * sizeof( opus_int32 ) ); | ||
93 | } | ||
94 | } | ||
95 | |||
96 | /* Low-pass filter with variable cutoff frequency based on */ | ||
97 | /* piece-wise linear interpolation between elliptic filters */ | ||
98 | /* Start by setting psEncC->mode <> 0; */ | ||
99 | /* Deactivate by setting psEncC->mode = 0; */ | ||
100 | void silk_LP_variable_cutoff( | ||
101 | silk_LP_state *psLP, /* I/O LP filter state */ | ||
102 | opus_int16 *frame, /* I/O Low-pass filtered output signal */ | ||
103 | const opus_int frame_length /* I Frame length */ | ||
104 | ) | ||
105 | { | ||
106 | opus_int32 B_Q28[ TRANSITION_NB ], A_Q28[ TRANSITION_NA ], fac_Q16 = 0; | ||
107 | opus_int ind = 0; | ||
108 | |||
109 | silk_assert( psLP->transition_frame_no >= 0 && psLP->transition_frame_no <= TRANSITION_FRAMES ); | ||
110 | |||
111 | /* Run filter if needed */ | ||
112 | if( psLP->mode != 0 ) { | ||
113 | /* Calculate index and interpolation factor for interpolation */ | ||
114 | #if( TRANSITION_INT_STEPS == 64 ) | ||
115 | fac_Q16 = silk_LSHIFT( TRANSITION_FRAMES - psLP->transition_frame_no, 16 - 6 ); | ||
116 | #else | ||
117 | fac_Q16 = silk_DIV32_16( silk_LSHIFT( TRANSITION_FRAMES - psLP->transition_frame_no, 16 ), TRANSITION_FRAMES ); | ||
118 | #endif | ||
119 | ind = silk_RSHIFT( fac_Q16, 16 ); | ||
120 | fac_Q16 -= silk_LSHIFT( ind, 16 ); | ||
121 | |||
122 | silk_assert( ind >= 0 ); | ||
123 | silk_assert( ind < TRANSITION_INT_NUM ); | ||
124 | |||
125 | /* Interpolate filter coefficients */ | ||
126 | silk_LP_interpolate_filter_taps( B_Q28, A_Q28, ind, fac_Q16 ); | ||
127 | |||
128 | /* Update transition frame number for next frame */ | ||
129 | psLP->transition_frame_no = silk_LIMIT( psLP->transition_frame_no + psLP->mode, 0, TRANSITION_FRAMES ); | ||
130 | |||
131 | /* ARMA low-pass filtering */ | ||
132 | silk_assert( TRANSITION_NB == 3 && TRANSITION_NA == 2 ); | ||
133 | silk_biquad_alt_stride1( frame, B_Q28, A_Q28, psLP->In_LP_State, frame, frame_length); | ||
134 | } | ||
135 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/MacroCount.h b/lib/rbcodec/codecs/libopus/silk/MacroCount.h index 834817d058..78100ffede 100644 --- a/lib/rbcodec/codecs/libopus/silk/MacroCount.h +++ b/lib/rbcodec/codecs/libopus/silk/MacroCount.h | |||
@@ -319,14 +319,6 @@ static OPUS_INLINE opus_int32 silk_ADD_POS_SAT32(opus_int64 a, opus_int64 b){ | |||
319 | return(tmp); | 319 | return(tmp); |
320 | } | 320 | } |
321 | 321 | ||
322 | #undef silk_ADD_POS_SAT64 | ||
323 | static OPUS_INLINE opus_int64 silk_ADD_POS_SAT64(opus_int64 a, opus_int64 b){ | ||
324 | opus_int64 tmp; | ||
325 | ops_count += 1; | ||
326 | tmp = ((((a)+(b)) & 0x8000000000000000LL) ? silk_int64_MAX : ((a)+(b))); | ||
327 | return(tmp); | ||
328 | } | ||
329 | |||
330 | #undef silk_LSHIFT8 | 322 | #undef silk_LSHIFT8 |
331 | static OPUS_INLINE opus_int8 silk_LSHIFT8(opus_int8 a, opus_int32 shift){ | 323 | static OPUS_INLINE opus_int8 silk_LSHIFT8(opus_int8 a, opus_int32 shift){ |
332 | opus_int8 ret; | 324 | opus_int8 ret; |
@@ -699,7 +691,7 @@ return(ret); | |||
699 | 691 | ||
700 | 692 | ||
701 | #undef silk_LIMIT_32 | 693 | #undef silk_LIMIT_32 |
702 | static OPUS_INLINE opus_int silk_LIMIT_32(opus_int32 a, opus_int32 limit1, opus_int32 limit2) | 694 | static OPUS_INLINE opus_int32 silk_LIMIT_32(opus_int32 a, opus_int32 limit1, opus_int32 limit2) |
703 | { | 695 | { |
704 | opus_int32 ret; | 696 | opus_int32 ret; |
705 | ops_count += 6; | 697 | ops_count += 6; |
diff --git a/lib/rbcodec/codecs/libopus/silk/MacroDebug.h b/lib/rbcodec/codecs/libopus/silk/MacroDebug.h index 35aedc5c5f..8dd4ce2ee2 100644 --- a/lib/rbcodec/codecs/libopus/silk/MacroDebug.h +++ b/lib/rbcodec/codecs/libopus/silk/MacroDebug.h | |||
@@ -539,8 +539,7 @@ static OPUS_INLINE opus_int32 silk_DIV32_16_(opus_int32 a32, opus_int32 b32, cha | |||
539 | no checking needed for silk_POS_SAT32 | 539 | no checking needed for silk_POS_SAT32 |
540 | no checking needed for silk_ADD_POS_SAT8 | 540 | no checking needed for silk_ADD_POS_SAT8 |
541 | no checking needed for silk_ADD_POS_SAT16 | 541 | no checking needed for silk_ADD_POS_SAT16 |
542 | no checking needed for silk_ADD_POS_SAT32 | 542 | no checking needed for silk_ADD_POS_SAT32 */ |
543 | no checking needed for silk_ADD_POS_SAT64 */ | ||
544 | 543 | ||
545 | #undef silk_LSHIFT8 | 544 | #undef silk_LSHIFT8 |
546 | #define silk_LSHIFT8(a,b) silk_LSHIFT8_((a), (b), __FILE__, __LINE__) | 545 | #define silk_LSHIFT8(a,b) silk_LSHIFT8_((a), (b), __FILE__, __LINE__) |
diff --git a/lib/rbcodec/codecs/libopus/silk/NLSF2A.c b/lib/rbcodec/codecs/libopus/silk/NLSF2A.c index b1c559ea68..d5b7730638 100644 --- a/lib/rbcodec/codecs/libopus/silk/NLSF2A.c +++ b/lib/rbcodec/codecs/libopus/silk/NLSF2A.c | |||
@@ -66,7 +66,8 @@ static OPUS_INLINE void silk_NLSF2A_find_poly( | |||
66 | void silk_NLSF2A( | 66 | void silk_NLSF2A( |
67 | opus_int16 *a_Q12, /* O monic whitening filter coefficients in Q12, [ d ] */ | 67 | opus_int16 *a_Q12, /* O monic whitening filter coefficients in Q12, [ d ] */ |
68 | const opus_int16 *NLSF, /* I normalized line spectral frequencies in Q15, [ d ] */ | 68 | const opus_int16 *NLSF, /* I normalized line spectral frequencies in Q15, [ d ] */ |
69 | const opus_int d /* I filter order (should be even) */ | 69 | const opus_int d, /* I filter order (should be even) */ |
70 | int arch /* I Run-time architecture */ | ||
70 | ) | 71 | ) |
71 | { | 72 | { |
72 | /* This ordering was found to maximize quality. It improves numerical accuracy of | 73 | /* This ordering was found to maximize quality. It improves numerical accuracy of |
@@ -83,15 +84,14 @@ void silk_NLSF2A( | |||
83 | opus_int32 P[ SILK_MAX_ORDER_LPC / 2 + 1 ], Q[ SILK_MAX_ORDER_LPC / 2 + 1 ]; | 84 | opus_int32 P[ SILK_MAX_ORDER_LPC / 2 + 1 ], Q[ SILK_MAX_ORDER_LPC / 2 + 1 ]; |
84 | opus_int32 Ptmp, Qtmp, f_int, f_frac, cos_val, delta; | 85 | opus_int32 Ptmp, Qtmp, f_int, f_frac, cos_val, delta; |
85 | opus_int32 a32_QA1[ SILK_MAX_ORDER_LPC ]; | 86 | opus_int32 a32_QA1[ SILK_MAX_ORDER_LPC ]; |
86 | opus_int32 maxabs, absval, idx=0, sc_Q16; | ||
87 | 87 | ||
88 | silk_assert( LSF_COS_TAB_SZ_FIX == 128 ); | 88 | silk_assert( LSF_COS_TAB_SZ_FIX == 128 ); |
89 | silk_assert( d==10||d==16 ); | 89 | celt_assert( d==10 || d==16 ); |
90 | 90 | ||
91 | /* convert LSFs to 2*cos(LSF), using piecewise linear curve from table */ | 91 | /* convert LSFs to 2*cos(LSF), using piecewise linear curve from table */ |
92 | ordering = d == 16 ? ordering16 : ordering10; | 92 | ordering = d == 16 ? ordering16 : ordering10; |
93 | for( k = 0; k < d; k++ ) { | 93 | for( k = 0; k < d; k++ ) { |
94 | silk_assert(NLSF[k] >= 0 ); | 94 | silk_assert( NLSF[k] >= 0 ); |
95 | 95 | ||
96 | /* f_int on a scale 0-127 (rounded down) */ | 96 | /* f_int on a scale 0-127 (rounded down) */ |
97 | f_int = silk_RSHIFT( NLSF[k], 15 - 7 ); | 97 | f_int = silk_RSHIFT( NLSF[k], 15 - 7 ); |
@@ -126,52 +126,15 @@ void silk_NLSF2A( | |||
126 | a32_QA1[ d-k-1 ] = Qtmp - Ptmp; /* QA+1 */ | 126 | a32_QA1[ d-k-1 ] = Qtmp - Ptmp; /* QA+1 */ |
127 | } | 127 | } |
128 | 128 | ||
129 | /* Limit the maximum absolute value of the prediction coefficients, so that they'll fit in int16 */ | 129 | /* Convert int32 coefficients to Q12 int16 coefs */ |
130 | for( i = 0; i < 10; i++ ) { | 130 | silk_LPC_fit( a_Q12, a32_QA1, 12, QA + 1, d ); |
131 | /* Find maximum absolute value and its index */ | ||
132 | maxabs = 0; | ||
133 | for( k = 0; k < d; k++ ) { | ||
134 | absval = silk_abs( a32_QA1[k] ); | ||
135 | if( absval > maxabs ) { | ||
136 | maxabs = absval; | ||
137 | idx = k; | ||
138 | } | ||
139 | } | ||
140 | maxabs = silk_RSHIFT_ROUND( maxabs, QA + 1 - 12 ); /* QA+1 -> Q12 */ | ||
141 | |||
142 | if( maxabs > silk_int16_MAX ) { | ||
143 | /* Reduce magnitude of prediction coefficients */ | ||
144 | maxabs = silk_min( maxabs, 163838 ); /* ( silk_int32_MAX >> 14 ) + silk_int16_MAX = 163838 */ | ||
145 | sc_Q16 = SILK_FIX_CONST( 0.999, 16 ) - silk_DIV32( silk_LSHIFT( maxabs - silk_int16_MAX, 14 ), | ||
146 | silk_RSHIFT32( silk_MUL( maxabs, idx + 1), 2 ) ); | ||
147 | silk_bwexpander_32( a32_QA1, d, sc_Q16 ); | ||
148 | } else { | ||
149 | break; | ||
150 | } | ||
151 | } | ||
152 | 131 | ||
153 | if( i == 10 ) { | 132 | for( i = 0; silk_LPC_inverse_pred_gain( a_Q12, d, arch ) == 0 && i < MAX_LPC_STABILIZE_ITERATIONS; i++ ) { |
154 | /* Reached the last iteration, clip the coefficients */ | 133 | /* Prediction coefficients are (too close to) unstable; apply bandwidth expansion */ |
134 | /* on the unscaled coefficients, convert to Q12 and measure again */ | ||
135 | silk_bwexpander_32( a32_QA1, d, 65536 - silk_LSHIFT( 2, i ) ); | ||
155 | for( k = 0; k < d; k++ ) { | 136 | for( k = 0; k < d; k++ ) { |
156 | a_Q12[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ) ); /* QA+1 -> Q12 */ | 137 | a_Q12[ k ] = (opus_int16)silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ); /* QA+1 -> Q12 */ |
157 | a32_QA1[ k ] = silk_LSHIFT( (opus_int32)a_Q12[ k ], QA + 1 - 12 ); | ||
158 | } | ||
159 | } else { | ||
160 | for( k = 0; k < d; k++ ) { | ||
161 | a_Q12[ k ] = (opus_int16)silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ); /* QA+1 -> Q12 */ | ||
162 | } | ||
163 | } | ||
164 | |||
165 | for( i = 0; i < MAX_LPC_STABILIZE_ITERATIONS; i++ ) { | ||
166 | if( silk_LPC_inverse_pred_gain( a_Q12, d ) < SILK_FIX_CONST( 1.0 / MAX_PREDICTION_POWER_GAIN, 30 ) ) { | ||
167 | /* Prediction coefficients are (too close to) unstable; apply bandwidth expansion */ | ||
168 | /* on the unscaled coefficients, convert to Q12 and measure again */ | ||
169 | silk_bwexpander_32( a32_QA1, d, 65536 - silk_LSHIFT( 2, i ) ); | ||
170 | for( k = 0; k < d; k++ ) { | ||
171 | a_Q12[ k ] = (opus_int16)silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ); /* QA+1 -> Q12 */ | ||
172 | } | ||
173 | } else { | ||
174 | break; | ||
175 | } | 138 | } |
176 | } | 139 | } |
177 | } | 140 | } |
diff --git a/lib/rbcodec/codecs/libopus/silk/NLSF_VQ.c b/lib/rbcodec/codecs/libopus/silk/NLSF_VQ.c new file mode 100644 index 0000000000..b83182a79c --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/NLSF_VQ.c | |||
@@ -0,0 +1,76 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main.h" | ||
33 | |||
34 | /* Compute quantization errors for an LPC_order element input vector for a VQ codebook */ | ||
35 | void silk_NLSF_VQ( | ||
36 | opus_int32 err_Q24[], /* O Quantization errors [K] */ | ||
37 | const opus_int16 in_Q15[], /* I Input vectors to be quantized [LPC_order] */ | ||
38 | const opus_uint8 pCB_Q8[], /* I Codebook vectors [K*LPC_order] */ | ||
39 | const opus_int16 pWght_Q9[], /* I Codebook weights [K*LPC_order] */ | ||
40 | const opus_int K, /* I Number of codebook vectors */ | ||
41 | const opus_int LPC_order /* I Number of LPCs */ | ||
42 | ) | ||
43 | { | ||
44 | opus_int i, m; | ||
45 | opus_int32 diff_Q15, diffw_Q24, sum_error_Q24, pred_Q24; | ||
46 | const opus_int16 *w_Q9_ptr; | ||
47 | const opus_uint8 *cb_Q8_ptr; | ||
48 | |||
49 | celt_assert( ( LPC_order & 1 ) == 0 ); | ||
50 | |||
51 | /* Loop over codebook */ | ||
52 | cb_Q8_ptr = pCB_Q8; | ||
53 | w_Q9_ptr = pWght_Q9; | ||
54 | for( i = 0; i < K; i++ ) { | ||
55 | sum_error_Q24 = 0; | ||
56 | pred_Q24 = 0; | ||
57 | for( m = LPC_order-2; m >= 0; m -= 2 ) { | ||
58 | /* Compute weighted absolute predictive quantization error for index m + 1 */ | ||
59 | diff_Q15 = silk_SUB_LSHIFT32( in_Q15[ m + 1 ], (opus_int32)cb_Q8_ptr[ m + 1 ], 7 ); /* range: [ -32767 : 32767 ]*/ | ||
60 | diffw_Q24 = silk_SMULBB( diff_Q15, w_Q9_ptr[ m + 1 ] ); | ||
61 | sum_error_Q24 = silk_ADD32( sum_error_Q24, silk_abs( silk_SUB_RSHIFT32( diffw_Q24, pred_Q24, 1 ) ) ); | ||
62 | pred_Q24 = diffw_Q24; | ||
63 | |||
64 | /* Compute weighted absolute predictive quantization error for index m */ | ||
65 | diff_Q15 = silk_SUB_LSHIFT32( in_Q15[ m ], (opus_int32)cb_Q8_ptr[ m ], 7 ); /* range: [ -32767 : 32767 ]*/ | ||
66 | diffw_Q24 = silk_SMULBB( diff_Q15, w_Q9_ptr[ m ] ); | ||
67 | sum_error_Q24 = silk_ADD32( sum_error_Q24, silk_abs( silk_SUB_RSHIFT32( diffw_Q24, pred_Q24, 1 ) ) ); | ||
68 | pred_Q24 = diffw_Q24; | ||
69 | |||
70 | silk_assert( sum_error_Q24 >= 0 ); | ||
71 | } | ||
72 | err_Q24[ i ] = sum_error_Q24; | ||
73 | cb_Q8_ptr += LPC_order; | ||
74 | w_Q9_ptr += LPC_order; | ||
75 | } | ||
76 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/NLSF_VQ_weights_laroia.c b/lib/rbcodec/codecs/libopus/silk/NLSF_VQ_weights_laroia.c index 04894c59ab..9873bcde10 100644 --- a/lib/rbcodec/codecs/libopus/silk/NLSF_VQ_weights_laroia.c +++ b/lib/rbcodec/codecs/libopus/silk/NLSF_VQ_weights_laroia.c | |||
@@ -48,8 +48,8 @@ void silk_NLSF_VQ_weights_laroia( | |||
48 | opus_int k; | 48 | opus_int k; |
49 | opus_int32 tmp1_int, tmp2_int; | 49 | opus_int32 tmp1_int, tmp2_int; |
50 | 50 | ||
51 | silk_assert( D > 0 ); | 51 | celt_assert( D > 0 ); |
52 | silk_assert( ( D & 1 ) == 0 ); | 52 | celt_assert( ( D & 1 ) == 0 ); |
53 | 53 | ||
54 | /* First value */ | 54 | /* First value */ |
55 | tmp1_int = silk_max_int( pNLSF_Q15[ 0 ], 1 ); | 55 | tmp1_int = silk_max_int( pNLSF_Q15[ 0 ], 1 ); |
diff --git a/lib/rbcodec/codecs/libopus/silk/NLSF_decode.c b/lib/rbcodec/codecs/libopus/silk/NLSF_decode.c index 9f715060b8..eeb0ba8c92 100644 --- a/lib/rbcodec/codecs/libopus/silk/NLSF_decode.c +++ b/lib/rbcodec/codecs/libopus/silk/NLSF_decode.c | |||
@@ -32,7 +32,7 @@ POSSIBILITY OF SUCH DAMAGE. | |||
32 | #include "main.h" | 32 | #include "main.h" |
33 | 33 | ||
34 | /* Predictive dequantizer for NLSF residuals */ | 34 | /* Predictive dequantizer for NLSF residuals */ |
35 | static OPUS_INLINE void silk_NLSF_residual_dequant( /* O Returns RD value in Q30 */ | 35 | static OPUS_INLINE void silk_NLSF_residual_dequant( /* O Returns RD value in Q30 */ |
36 | opus_int16 x_Q10[], /* O Output [ order ] */ | 36 | opus_int16 x_Q10[], /* O Output [ order ] */ |
37 | const opus_int8 indices[], /* I Quantization indices [ order ] */ | 37 | const opus_int8 indices[], /* I Quantization indices [ order ] */ |
38 | const opus_uint8 pred_coef_Q8[], /* I Backward predictor coefs [ order ] */ | 38 | const opus_uint8 pred_coef_Q8[], /* I Backward predictor coefs [ order ] */ |
@@ -70,15 +70,9 @@ void silk_NLSF_decode( | |||
70 | opus_uint8 pred_Q8[ MAX_LPC_ORDER ]; | 70 | opus_uint8 pred_Q8[ MAX_LPC_ORDER ]; |
71 | opus_int16 ec_ix[ MAX_LPC_ORDER ]; | 71 | opus_int16 ec_ix[ MAX_LPC_ORDER ]; |
72 | opus_int16 res_Q10[ MAX_LPC_ORDER ]; | 72 | opus_int16 res_Q10[ MAX_LPC_ORDER ]; |
73 | opus_int16 W_tmp_QW[ MAX_LPC_ORDER ]; | 73 | opus_int32 NLSF_Q15_tmp; |
74 | opus_int32 W_tmp_Q9, NLSF_Q15_tmp; | ||
75 | const opus_uint8 *pCB_element; | 74 | const opus_uint8 *pCB_element; |
76 | 75 | const opus_int16 *pCB_Wght_Q9; | |
77 | /* Decode first stage */ | ||
78 | pCB_element = &psNLSF_CB->CB1_NLSF_Q8[ NLSFIndices[ 0 ] * psNLSF_CB->order ]; | ||
79 | for( i = 0; i < psNLSF_CB->order; i++ ) { | ||
80 | pNLSF_Q15[ i ] = silk_LSHIFT( (opus_int16)pCB_element[ i ], 7 ); | ||
81 | } | ||
82 | 76 | ||
83 | /* Unpack entropy table indices and predictor for current CB1 index */ | 77 | /* Unpack entropy table indices and predictor for current CB1 index */ |
84 | silk_NLSF_unpack( ec_ix, pred_Q8, psNLSF_CB, NLSFIndices[ 0 ] ); | 78 | silk_NLSF_unpack( ec_ix, pred_Q8, psNLSF_CB, NLSFIndices[ 0 ] ); |
@@ -86,13 +80,11 @@ void silk_NLSF_decode( | |||
86 | /* Predictive residual dequantizer */ | 80 | /* Predictive residual dequantizer */ |
87 | silk_NLSF_residual_dequant( res_Q10, &NLSFIndices[ 1 ], pred_Q8, psNLSF_CB->quantStepSize_Q16, psNLSF_CB->order ); | 81 | silk_NLSF_residual_dequant( res_Q10, &NLSFIndices[ 1 ], pred_Q8, psNLSF_CB->quantStepSize_Q16, psNLSF_CB->order ); |
88 | 82 | ||
89 | /* Weights from codebook vector */ | 83 | /* Apply inverse square-rooted weights to first stage and add to output */ |
90 | silk_NLSF_VQ_weights_laroia( W_tmp_QW, pNLSF_Q15, psNLSF_CB->order ); | 84 | pCB_element = &psNLSF_CB->CB1_NLSF_Q8[ NLSFIndices[ 0 ] * psNLSF_CB->order ]; |
91 | 85 | pCB_Wght_Q9 = &psNLSF_CB->CB1_Wght_Q9[ NLSFIndices[ 0 ] * psNLSF_CB->order ]; | |
92 | /* Apply inverse square-rooted weights and add to output */ | ||
93 | for( i = 0; i < psNLSF_CB->order; i++ ) { | 86 | for( i = 0; i < psNLSF_CB->order; i++ ) { |
94 | W_tmp_Q9 = silk_SQRT_APPROX( silk_LSHIFT( (opus_int32)W_tmp_QW[ i ], 18 - NLSF_W_Q ) ); | 87 | NLSF_Q15_tmp = silk_ADD_LSHIFT32( silk_DIV32_16( silk_LSHIFT( (opus_int32)res_Q10[ i ], 14 ), pCB_Wght_Q9[ i ] ), (opus_int16)pCB_element[ i ], 7 ); |
95 | NLSF_Q15_tmp = silk_ADD32( pNLSF_Q15[ i ], silk_DIV32_16( silk_LSHIFT( (opus_int32)res_Q10[ i ], 14 ), W_tmp_Q9 ) ); | ||
96 | pNLSF_Q15[ i ] = (opus_int16)silk_LIMIT( NLSF_Q15_tmp, 0, 32767 ); | 88 | pNLSF_Q15[ i ] = (opus_int16)silk_LIMIT( NLSF_Q15_tmp, 0, 32767 ); |
97 | } | 89 | } |
98 | 90 | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/NLSF_del_dec_quant.c b/lib/rbcodec/codecs/libopus/silk/NLSF_del_dec_quant.c new file mode 100644 index 0000000000..44a16acd0b --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/NLSF_del_dec_quant.c | |||
@@ -0,0 +1,215 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main.h" | ||
33 | |||
34 | /* Delayed-decision quantizer for NLSF residuals */ | ||
35 | opus_int32 silk_NLSF_del_dec_quant( /* O Returns RD value in Q25 */ | ||
36 | opus_int8 indices[], /* O Quantization indices [ order ] */ | ||
37 | const opus_int16 x_Q10[], /* I Input [ order ] */ | ||
38 | const opus_int16 w_Q5[], /* I Weights [ order ] */ | ||
39 | const opus_uint8 pred_coef_Q8[], /* I Backward predictor coefs [ order ] */ | ||
40 | const opus_int16 ec_ix[], /* I Indices to entropy coding tables [ order ] */ | ||
41 | const opus_uint8 ec_rates_Q5[], /* I Rates [] */ | ||
42 | const opus_int quant_step_size_Q16, /* I Quantization step size */ | ||
43 | const opus_int16 inv_quant_step_size_Q6, /* I Inverse quantization step size */ | ||
44 | const opus_int32 mu_Q20, /* I R/D tradeoff */ | ||
45 | const opus_int16 order /* I Number of input values */ | ||
46 | ) | ||
47 | { | ||
48 | opus_int i, j, nStates, ind_tmp, ind_min_max, ind_max_min, in_Q10, res_Q10; | ||
49 | opus_int pred_Q10, diff_Q10, rate0_Q5, rate1_Q5; | ||
50 | opus_int16 out0_Q10, out1_Q10; | ||
51 | opus_int32 RD_tmp_Q25, min_Q25, min_max_Q25, max_min_Q25; | ||
52 | opus_int ind_sort[ NLSF_QUANT_DEL_DEC_STATES ]; | ||
53 | opus_int8 ind[ NLSF_QUANT_DEL_DEC_STATES ][ MAX_LPC_ORDER ]; | ||
54 | opus_int16 prev_out_Q10[ 2 * NLSF_QUANT_DEL_DEC_STATES ]; | ||
55 | opus_int32 RD_Q25[ 2 * NLSF_QUANT_DEL_DEC_STATES ]; | ||
56 | opus_int32 RD_min_Q25[ NLSF_QUANT_DEL_DEC_STATES ]; | ||
57 | opus_int32 RD_max_Q25[ NLSF_QUANT_DEL_DEC_STATES ]; | ||
58 | const opus_uint8 *rates_Q5; | ||
59 | |||
60 | opus_int out0_Q10_table[2 * NLSF_QUANT_MAX_AMPLITUDE_EXT]; | ||
61 | opus_int out1_Q10_table[2 * NLSF_QUANT_MAX_AMPLITUDE_EXT]; | ||
62 | |||
63 | for (i = -NLSF_QUANT_MAX_AMPLITUDE_EXT; i <= NLSF_QUANT_MAX_AMPLITUDE_EXT-1; i++) | ||
64 | { | ||
65 | out0_Q10 = silk_LSHIFT( i, 10 ); | ||
66 | out1_Q10 = silk_ADD16( out0_Q10, 1024 ); | ||
67 | if( i > 0 ) { | ||
68 | out0_Q10 = silk_SUB16( out0_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) ); | ||
69 | out1_Q10 = silk_SUB16( out1_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) ); | ||
70 | } else if( i == 0 ) { | ||
71 | out1_Q10 = silk_SUB16( out1_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) ); | ||
72 | } else if( i == -1 ) { | ||
73 | out0_Q10 = silk_ADD16( out0_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) ); | ||
74 | } else { | ||
75 | out0_Q10 = silk_ADD16( out0_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) ); | ||
76 | out1_Q10 = silk_ADD16( out1_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) ); | ||
77 | } | ||
78 | out0_Q10_table[ i + NLSF_QUANT_MAX_AMPLITUDE_EXT ] = silk_RSHIFT( silk_SMULBB( out0_Q10, quant_step_size_Q16 ), 16 ); | ||
79 | out1_Q10_table[ i + NLSF_QUANT_MAX_AMPLITUDE_EXT ] = silk_RSHIFT( silk_SMULBB( out1_Q10, quant_step_size_Q16 ), 16 ); | ||
80 | } | ||
81 | |||
82 | silk_assert( (NLSF_QUANT_DEL_DEC_STATES & (NLSF_QUANT_DEL_DEC_STATES-1)) == 0 ); /* must be power of two */ | ||
83 | |||
84 | nStates = 1; | ||
85 | RD_Q25[ 0 ] = 0; | ||
86 | prev_out_Q10[ 0 ] = 0; | ||
87 | for( i = order - 1; i >= 0; i-- ) { | ||
88 | rates_Q5 = &ec_rates_Q5[ ec_ix[ i ] ]; | ||
89 | in_Q10 = x_Q10[ i ]; | ||
90 | for( j = 0; j < nStates; j++ ) { | ||
91 | pred_Q10 = silk_RSHIFT( silk_SMULBB( (opus_int16)pred_coef_Q8[ i ], prev_out_Q10[ j ] ), 8 ); | ||
92 | res_Q10 = silk_SUB16( in_Q10, pred_Q10 ); | ||
93 | ind_tmp = silk_RSHIFT( silk_SMULBB( inv_quant_step_size_Q6, res_Q10 ), 16 ); | ||
94 | ind_tmp = silk_LIMIT( ind_tmp, -NLSF_QUANT_MAX_AMPLITUDE_EXT, NLSF_QUANT_MAX_AMPLITUDE_EXT-1 ); | ||
95 | ind[ j ][ i ] = (opus_int8)ind_tmp; | ||
96 | |||
97 | /* compute outputs for ind_tmp and ind_tmp + 1 */ | ||
98 | out0_Q10 = out0_Q10_table[ ind_tmp + NLSF_QUANT_MAX_AMPLITUDE_EXT ]; | ||
99 | out1_Q10 = out1_Q10_table[ ind_tmp + NLSF_QUANT_MAX_AMPLITUDE_EXT ]; | ||
100 | |||
101 | out0_Q10 = silk_ADD16( out0_Q10, pred_Q10 ); | ||
102 | out1_Q10 = silk_ADD16( out1_Q10, pred_Q10 ); | ||
103 | prev_out_Q10[ j ] = out0_Q10; | ||
104 | prev_out_Q10[ j + nStates ] = out1_Q10; | ||
105 | |||
106 | /* compute RD for ind_tmp and ind_tmp + 1 */ | ||
107 | if( ind_tmp + 1 >= NLSF_QUANT_MAX_AMPLITUDE ) { | ||
108 | if( ind_tmp + 1 == NLSF_QUANT_MAX_AMPLITUDE ) { | ||
109 | rate0_Q5 = rates_Q5[ ind_tmp + NLSF_QUANT_MAX_AMPLITUDE ]; | ||
110 | rate1_Q5 = 280; | ||
111 | } else { | ||
112 | rate0_Q5 = silk_SMLABB( 280 - 43 * NLSF_QUANT_MAX_AMPLITUDE, 43, ind_tmp ); | ||
113 | rate1_Q5 = silk_ADD16( rate0_Q5, 43 ); | ||
114 | } | ||
115 | } else if( ind_tmp <= -NLSF_QUANT_MAX_AMPLITUDE ) { | ||
116 | if( ind_tmp == -NLSF_QUANT_MAX_AMPLITUDE ) { | ||
117 | rate0_Q5 = 280; | ||
118 | rate1_Q5 = rates_Q5[ ind_tmp + 1 + NLSF_QUANT_MAX_AMPLITUDE ]; | ||
119 | } else { | ||
120 | rate0_Q5 = silk_SMLABB( 280 - 43 * NLSF_QUANT_MAX_AMPLITUDE, -43, ind_tmp ); | ||
121 | rate1_Q5 = silk_SUB16( rate0_Q5, 43 ); | ||
122 | } | ||
123 | } else { | ||
124 | rate0_Q5 = rates_Q5[ ind_tmp + NLSF_QUANT_MAX_AMPLITUDE ]; | ||
125 | rate1_Q5 = rates_Q5[ ind_tmp + 1 + NLSF_QUANT_MAX_AMPLITUDE ]; | ||
126 | } | ||
127 | RD_tmp_Q25 = RD_Q25[ j ]; | ||
128 | diff_Q10 = silk_SUB16( in_Q10, out0_Q10 ); | ||
129 | RD_Q25[ j ] = silk_SMLABB( silk_MLA( RD_tmp_Q25, silk_SMULBB( diff_Q10, diff_Q10 ), w_Q5[ i ] ), mu_Q20, rate0_Q5 ); | ||
130 | diff_Q10 = silk_SUB16( in_Q10, out1_Q10 ); | ||
131 | RD_Q25[ j + nStates ] = silk_SMLABB( silk_MLA( RD_tmp_Q25, silk_SMULBB( diff_Q10, diff_Q10 ), w_Q5[ i ] ), mu_Q20, rate1_Q5 ); | ||
132 | } | ||
133 | |||
134 | if( nStates <= NLSF_QUANT_DEL_DEC_STATES/2 ) { | ||
135 | /* double number of states and copy */ | ||
136 | for( j = 0; j < nStates; j++ ) { | ||
137 | ind[ j + nStates ][ i ] = ind[ j ][ i ] + 1; | ||
138 | } | ||
139 | nStates = silk_LSHIFT( nStates, 1 ); | ||
140 | for( j = nStates; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) { | ||
141 | ind[ j ][ i ] = ind[ j - nStates ][ i ]; | ||
142 | } | ||
143 | } else { | ||
144 | /* sort lower and upper half of RD_Q25, pairwise */ | ||
145 | for( j = 0; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) { | ||
146 | if( RD_Q25[ j ] > RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ] ) { | ||
147 | RD_max_Q25[ j ] = RD_Q25[ j ]; | ||
148 | RD_min_Q25[ j ] = RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ]; | ||
149 | RD_Q25[ j ] = RD_min_Q25[ j ]; | ||
150 | RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ] = RD_max_Q25[ j ]; | ||
151 | /* swap prev_out values */ | ||
152 | out0_Q10 = prev_out_Q10[ j ]; | ||
153 | prev_out_Q10[ j ] = prev_out_Q10[ j + NLSF_QUANT_DEL_DEC_STATES ]; | ||
154 | prev_out_Q10[ j + NLSF_QUANT_DEL_DEC_STATES ] = out0_Q10; | ||
155 | ind_sort[ j ] = j + NLSF_QUANT_DEL_DEC_STATES; | ||
156 | } else { | ||
157 | RD_min_Q25[ j ] = RD_Q25[ j ]; | ||
158 | RD_max_Q25[ j ] = RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ]; | ||
159 | ind_sort[ j ] = j; | ||
160 | } | ||
161 | } | ||
162 | /* compare the highest RD values of the winning half with the lowest one in the losing half, and copy if necessary */ | ||
163 | /* afterwards ind_sort[] will contain the indices of the NLSF_QUANT_DEL_DEC_STATES winning RD values */ | ||
164 | while( 1 ) { | ||
165 | min_max_Q25 = silk_int32_MAX; | ||
166 | max_min_Q25 = 0; | ||
167 | ind_min_max = 0; | ||
168 | ind_max_min = 0; | ||
169 | for( j = 0; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) { | ||
170 | if( min_max_Q25 > RD_max_Q25[ j ] ) { | ||
171 | min_max_Q25 = RD_max_Q25[ j ]; | ||
172 | ind_min_max = j; | ||
173 | } | ||
174 | if( max_min_Q25 < RD_min_Q25[ j ] ) { | ||
175 | max_min_Q25 = RD_min_Q25[ j ]; | ||
176 | ind_max_min = j; | ||
177 | } | ||
178 | } | ||
179 | if( min_max_Q25 >= max_min_Q25 ) { | ||
180 | break; | ||
181 | } | ||
182 | /* copy ind_min_max to ind_max_min */ | ||
183 | ind_sort[ ind_max_min ] = ind_sort[ ind_min_max ] ^ NLSF_QUANT_DEL_DEC_STATES; | ||
184 | RD_Q25[ ind_max_min ] = RD_Q25[ ind_min_max + NLSF_QUANT_DEL_DEC_STATES ]; | ||
185 | prev_out_Q10[ ind_max_min ] = prev_out_Q10[ ind_min_max + NLSF_QUANT_DEL_DEC_STATES ]; | ||
186 | RD_min_Q25[ ind_max_min ] = 0; | ||
187 | RD_max_Q25[ ind_min_max ] = silk_int32_MAX; | ||
188 | silk_memcpy( ind[ ind_max_min ], ind[ ind_min_max ], MAX_LPC_ORDER * sizeof( opus_int8 ) ); | ||
189 | } | ||
190 | /* increment index if it comes from the upper half */ | ||
191 | for( j = 0; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) { | ||
192 | ind[ j ][ i ] += silk_RSHIFT( ind_sort[ j ], NLSF_QUANT_DEL_DEC_STATES_LOG2 ); | ||
193 | } | ||
194 | } | ||
195 | } | ||
196 | |||
197 | /* last sample: find winner, copy indices and return RD value */ | ||
198 | ind_tmp = 0; | ||
199 | min_Q25 = silk_int32_MAX; | ||
200 | for( j = 0; j < 2 * NLSF_QUANT_DEL_DEC_STATES; j++ ) { | ||
201 | if( min_Q25 > RD_Q25[ j ] ) { | ||
202 | min_Q25 = RD_Q25[ j ]; | ||
203 | ind_tmp = j; | ||
204 | } | ||
205 | } | ||
206 | for( j = 0; j < order; j++ ) { | ||
207 | indices[ j ] = ind[ ind_tmp & ( NLSF_QUANT_DEL_DEC_STATES - 1 ) ][ j ]; | ||
208 | silk_assert( indices[ j ] >= -NLSF_QUANT_MAX_AMPLITUDE_EXT ); | ||
209 | silk_assert( indices[ j ] <= NLSF_QUANT_MAX_AMPLITUDE_EXT ); | ||
210 | } | ||
211 | indices[ 0 ] += silk_RSHIFT( ind_tmp, NLSF_QUANT_DEL_DEC_STATES_LOG2 ); | ||
212 | silk_assert( indices[ 0 ] <= NLSF_QUANT_MAX_AMPLITUDE_EXT ); | ||
213 | silk_assert( min_Q25 >= 0 ); | ||
214 | return min_Q25; | ||
215 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/NLSF_encode.c b/lib/rbcodec/codecs/libopus/silk/NLSF_encode.c new file mode 100644 index 0000000000..01ac7db78c --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/NLSF_encode.c | |||
@@ -0,0 +1,124 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main.h" | ||
33 | #include "stack_alloc.h" | ||
34 | |||
35 | /***********************/ | ||
36 | /* NLSF vector encoder */ | ||
37 | /***********************/ | ||
38 | opus_int32 silk_NLSF_encode( /* O Returns RD value in Q25 */ | ||
39 | opus_int8 *NLSFIndices, /* I Codebook path vector [ LPC_ORDER + 1 ] */ | ||
40 | opus_int16 *pNLSF_Q15, /* I/O (Un)quantized NLSF vector [ LPC_ORDER ] */ | ||
41 | const silk_NLSF_CB_struct *psNLSF_CB, /* I Codebook object */ | ||
42 | const opus_int16 *pW_Q2, /* I NLSF weight vector [ LPC_ORDER ] */ | ||
43 | const opus_int NLSF_mu_Q20, /* I Rate weight for the RD optimization */ | ||
44 | const opus_int nSurvivors, /* I Max survivors after first stage */ | ||
45 | const opus_int signalType /* I Signal type: 0/1/2 */ | ||
46 | ) | ||
47 | { | ||
48 | opus_int i, s, ind1, bestIndex, prob_Q8, bits_q7; | ||
49 | opus_int32 W_tmp_Q9, ret; | ||
50 | VARDECL( opus_int32, err_Q24 ); | ||
51 | VARDECL( opus_int32, RD_Q25 ); | ||
52 | VARDECL( opus_int, tempIndices1 ); | ||
53 | VARDECL( opus_int8, tempIndices2 ); | ||
54 | opus_int16 res_Q10[ MAX_LPC_ORDER ]; | ||
55 | opus_int16 NLSF_tmp_Q15[ MAX_LPC_ORDER ]; | ||
56 | opus_int16 W_adj_Q5[ MAX_LPC_ORDER ]; | ||
57 | opus_uint8 pred_Q8[ MAX_LPC_ORDER ]; | ||
58 | opus_int16 ec_ix[ MAX_LPC_ORDER ]; | ||
59 | const opus_uint8 *pCB_element, *iCDF_ptr; | ||
60 | const opus_int16 *pCB_Wght_Q9; | ||
61 | SAVE_STACK; | ||
62 | |||
63 | celt_assert( signalType >= 0 && signalType <= 2 ); | ||
64 | silk_assert( NLSF_mu_Q20 <= 32767 && NLSF_mu_Q20 >= 0 ); | ||
65 | |||
66 | /* NLSF stabilization */ | ||
67 | silk_NLSF_stabilize( pNLSF_Q15, psNLSF_CB->deltaMin_Q15, psNLSF_CB->order ); | ||
68 | |||
69 | /* First stage: VQ */ | ||
70 | ALLOC( err_Q24, psNLSF_CB->nVectors, opus_int32 ); | ||
71 | silk_NLSF_VQ( err_Q24, pNLSF_Q15, psNLSF_CB->CB1_NLSF_Q8, psNLSF_CB->CB1_Wght_Q9, psNLSF_CB->nVectors, psNLSF_CB->order ); | ||
72 | |||
73 | /* Sort the quantization errors */ | ||
74 | ALLOC( tempIndices1, nSurvivors, opus_int ); | ||
75 | silk_insertion_sort_increasing( err_Q24, tempIndices1, psNLSF_CB->nVectors, nSurvivors ); | ||
76 | |||
77 | ALLOC( RD_Q25, nSurvivors, opus_int32 ); | ||
78 | ALLOC( tempIndices2, nSurvivors * MAX_LPC_ORDER, opus_int8 ); | ||
79 | |||
80 | /* Loop over survivors */ | ||
81 | for( s = 0; s < nSurvivors; s++ ) { | ||
82 | ind1 = tempIndices1[ s ]; | ||
83 | |||
84 | /* Residual after first stage */ | ||
85 | pCB_element = &psNLSF_CB->CB1_NLSF_Q8[ ind1 * psNLSF_CB->order ]; | ||
86 | pCB_Wght_Q9 = &psNLSF_CB->CB1_Wght_Q9[ ind1 * psNLSF_CB->order ]; | ||
87 | for( i = 0; i < psNLSF_CB->order; i++ ) { | ||
88 | NLSF_tmp_Q15[ i ] = silk_LSHIFT16( (opus_int16)pCB_element[ i ], 7 ); | ||
89 | W_tmp_Q9 = pCB_Wght_Q9[ i ]; | ||
90 | res_Q10[ i ] = (opus_int16)silk_RSHIFT( silk_SMULBB( pNLSF_Q15[ i ] - NLSF_tmp_Q15[ i ], W_tmp_Q9 ), 14 ); | ||
91 | W_adj_Q5[ i ] = silk_DIV32_varQ( (opus_int32)pW_Q2[ i ], silk_SMULBB( W_tmp_Q9, W_tmp_Q9 ), 21 ); | ||
92 | } | ||
93 | |||
94 | /* Unpack entropy table indices and predictor for current CB1 index */ | ||
95 | silk_NLSF_unpack( ec_ix, pred_Q8, psNLSF_CB, ind1 ); | ||
96 | |||
97 | /* Trellis quantizer */ | ||
98 | RD_Q25[ s ] = silk_NLSF_del_dec_quant( &tempIndices2[ s * MAX_LPC_ORDER ], res_Q10, W_adj_Q5, pred_Q8, ec_ix, | ||
99 | psNLSF_CB->ec_Rates_Q5, psNLSF_CB->quantStepSize_Q16, psNLSF_CB->invQuantStepSize_Q6, NLSF_mu_Q20, psNLSF_CB->order ); | ||
100 | |||
101 | /* Add rate for first stage */ | ||
102 | iCDF_ptr = &psNLSF_CB->CB1_iCDF[ ( signalType >> 1 ) * psNLSF_CB->nVectors ]; | ||
103 | if( ind1 == 0 ) { | ||
104 | prob_Q8 = 256 - iCDF_ptr[ ind1 ]; | ||
105 | } else { | ||
106 | prob_Q8 = iCDF_ptr[ ind1 - 1 ] - iCDF_ptr[ ind1 ]; | ||
107 | } | ||
108 | bits_q7 = ( 8 << 7 ) - silk_lin2log( prob_Q8 ); | ||
109 | RD_Q25[ s ] = silk_SMLABB( RD_Q25[ s ], bits_q7, silk_RSHIFT( NLSF_mu_Q20, 2 ) ); | ||
110 | } | ||
111 | |||
112 | /* Find the lowest rate-distortion error */ | ||
113 | silk_insertion_sort_increasing( RD_Q25, &bestIndex, nSurvivors, 1 ); | ||
114 | |||
115 | NLSFIndices[ 0 ] = (opus_int8)tempIndices1[ bestIndex ]; | ||
116 | silk_memcpy( &NLSFIndices[ 1 ], &tempIndices2[ bestIndex * MAX_LPC_ORDER ], psNLSF_CB->order * sizeof( opus_int8 ) ); | ||
117 | |||
118 | /* Decode */ | ||
119 | silk_NLSF_decode( pNLSF_Q15, NLSFIndices, psNLSF_CB ); | ||
120 | |||
121 | ret = RD_Q25[ 0 ]; | ||
122 | RESTORE_STACK; | ||
123 | return ret; | ||
124 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/NLSF_stabilize.c b/lib/rbcodec/codecs/libopus/silk/NLSF_stabilize.c index 1fa1ea379b..8f3426b91e 100644 --- a/lib/rbcodec/codecs/libopus/silk/NLSF_stabilize.c +++ b/lib/rbcodec/codecs/libopus/silk/NLSF_stabilize.c | |||
@@ -130,7 +130,7 @@ void silk_NLSF_stabilize( | |||
130 | 130 | ||
131 | /* Keep delta_min distance between the NLSFs */ | 131 | /* Keep delta_min distance between the NLSFs */ |
132 | for( i = 1; i < L; i++ ) | 132 | for( i = 1; i < L; i++ ) |
133 | NLSF_Q15[i] = silk_max_int( NLSF_Q15[i], NLSF_Q15[i-1] + NDeltaMin_Q15[i] ); | 133 | NLSF_Q15[i] = silk_max_int( NLSF_Q15[i], silk_ADD_SAT16( NLSF_Q15[i-1], NDeltaMin_Q15[i] ) ); |
134 | 134 | ||
135 | /* Last NLSF should be no higher than 1 - NDeltaMin[L] */ | 135 | /* Last NLSF should be no higher than 1 - NDeltaMin[L] */ |
136 | NLSF_Q15[L-1] = silk_min_int( NLSF_Q15[L-1], (1<<15) - NDeltaMin_Q15[L] ); | 136 | NLSF_Q15[L-1] = silk_min_int( NLSF_Q15[L-1], (1<<15) - NDeltaMin_Q15[L] ); |
diff --git a/lib/rbcodec/codecs/libopus/silk/NSQ.c b/lib/rbcodec/codecs/libopus/silk/NSQ.c new file mode 100644 index 0000000000..1d64d8e257 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/NSQ.c | |||
@@ -0,0 +1,437 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main.h" | ||
33 | #include "stack_alloc.h" | ||
34 | #include "NSQ.h" | ||
35 | |||
36 | |||
37 | static OPUS_INLINE void silk_nsq_scale_states( | ||
38 | const silk_encoder_state *psEncC, /* I Encoder State */ | ||
39 | silk_nsq_state *NSQ, /* I/O NSQ state */ | ||
40 | const opus_int16 x16[], /* I input */ | ||
41 | opus_int32 x_sc_Q10[], /* O input scaled with 1/Gain */ | ||
42 | const opus_int16 sLTP[], /* I re-whitened LTP state in Q0 */ | ||
43 | opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ | ||
44 | opus_int subfr, /* I subframe number */ | ||
45 | const opus_int LTP_scale_Q14, /* I */ | ||
46 | const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ | ||
47 | const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */ | ||
48 | const opus_int signal_type /* I Signal type */ | ||
49 | ); | ||
50 | |||
51 | #if !defined(OPUS_X86_MAY_HAVE_SSE4_1) | ||
52 | static OPUS_INLINE void silk_noise_shape_quantizer( | ||
53 | silk_nsq_state *NSQ, /* I/O NSQ state */ | ||
54 | opus_int signalType, /* I Signal type */ | ||
55 | const opus_int32 x_sc_Q10[], /* I */ | ||
56 | opus_int8 pulses[], /* O */ | ||
57 | opus_int16 xq[], /* O */ | ||
58 | opus_int32 sLTP_Q15[], /* I/O LTP state */ | ||
59 | const opus_int16 a_Q12[], /* I Short term prediction coefs */ | ||
60 | const opus_int16 b_Q14[], /* I Long term prediction coefs */ | ||
61 | const opus_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */ | ||
62 | opus_int lag, /* I Pitch lag */ | ||
63 | opus_int32 HarmShapeFIRPacked_Q14, /* I */ | ||
64 | opus_int Tilt_Q14, /* I Spectral tilt */ | ||
65 | opus_int32 LF_shp_Q14, /* I */ | ||
66 | opus_int32 Gain_Q16, /* I */ | ||
67 | opus_int Lambda_Q10, /* I */ | ||
68 | opus_int offset_Q10, /* I */ | ||
69 | opus_int length, /* I Input length */ | ||
70 | opus_int shapingLPCOrder, /* I Noise shaping AR filter order */ | ||
71 | opus_int predictLPCOrder, /* I Prediction filter order */ | ||
72 | int arch /* I Architecture */ | ||
73 | ); | ||
74 | #endif | ||
75 | |||
76 | void silk_NSQ_c | ||
77 | ( | ||
78 | const silk_encoder_state *psEncC, /* I Encoder State */ | ||
79 | silk_nsq_state *NSQ, /* I/O NSQ state */ | ||
80 | SideInfoIndices *psIndices, /* I/O Quantization Indices */ | ||
81 | const opus_int16 x16[], /* I Input */ | ||
82 | opus_int8 pulses[], /* O Quantized pulse signal */ | ||
83 | const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ | ||
84 | const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ | ||
85 | const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ | ||
86 | const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ | ||
87 | const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ | ||
88 | const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ | ||
89 | const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ | ||
90 | const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ | ||
91 | const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ | ||
92 | const opus_int LTP_scale_Q14 /* I LTP state scaling */ | ||
93 | ) | ||
94 | { | ||
95 | opus_int k, lag, start_idx, LSF_interpolation_flag; | ||
96 | const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13; | ||
97 | opus_int16 *pxq; | ||
98 | VARDECL( opus_int32, sLTP_Q15 ); | ||
99 | VARDECL( opus_int16, sLTP ); | ||
100 | opus_int32 HarmShapeFIRPacked_Q14; | ||
101 | opus_int offset_Q10; | ||
102 | VARDECL( opus_int32, x_sc_Q10 ); | ||
103 | SAVE_STACK; | ||
104 | |||
105 | NSQ->rand_seed = psIndices->Seed; | ||
106 | |||
107 | /* Set unvoiced lag to the previous one, overwrite later for voiced */ | ||
108 | lag = NSQ->lagPrev; | ||
109 | |||
110 | silk_assert( NSQ->prev_gain_Q16 != 0 ); | ||
111 | |||
112 | offset_Q10 = silk_Quantization_Offsets_Q10[ psIndices->signalType >> 1 ][ psIndices->quantOffsetType ]; | ||
113 | |||
114 | if( psIndices->NLSFInterpCoef_Q2 == 4 ) { | ||
115 | LSF_interpolation_flag = 0; | ||
116 | } else { | ||
117 | LSF_interpolation_flag = 1; | ||
118 | } | ||
119 | |||
120 | ALLOC( sLTP_Q15, psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 ); | ||
121 | ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 ); | ||
122 | ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 ); | ||
123 | /* Set up pointers to start of sub frame */ | ||
124 | NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length; | ||
125 | NSQ->sLTP_buf_idx = psEncC->ltp_mem_length; | ||
126 | pxq = &NSQ->xq[ psEncC->ltp_mem_length ]; | ||
127 | for( k = 0; k < psEncC->nb_subfr; k++ ) { | ||
128 | A_Q12 = &PredCoef_Q12[ (( k >> 1 ) | ( 1 - LSF_interpolation_flag )) * MAX_LPC_ORDER ]; | ||
129 | B_Q14 = <PCoef_Q14[ k * LTP_ORDER ]; | ||
130 | AR_shp_Q13 = &AR_Q13[ k * MAX_SHAPE_LPC_ORDER ]; | ||
131 | |||
132 | /* Noise shape parameters */ | ||
133 | silk_assert( HarmShapeGain_Q14[ k ] >= 0 ); | ||
134 | HarmShapeFIRPacked_Q14 = silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 ); | ||
135 | HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 ); | ||
136 | |||
137 | NSQ->rewhite_flag = 0; | ||
138 | if( psIndices->signalType == TYPE_VOICED ) { | ||
139 | /* Voiced */ | ||
140 | lag = pitchL[ k ]; | ||
141 | |||
142 | /* Re-whitening */ | ||
143 | if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) { | ||
144 | /* Rewhiten with new A coefs */ | ||
145 | start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2; | ||
146 | celt_assert( start_idx > 0 ); | ||
147 | |||
148 | silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ], | ||
149 | A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder, psEncC->arch ); | ||
150 | |||
151 | NSQ->rewhite_flag = 1; | ||
152 | NSQ->sLTP_buf_idx = psEncC->ltp_mem_length; | ||
153 | } | ||
154 | } | ||
155 | |||
156 | silk_nsq_scale_states( psEncC, NSQ, x16, x_sc_Q10, sLTP, sLTP_Q15, k, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType ); | ||
157 | |||
158 | silk_noise_shape_quantizer( NSQ, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15, A_Q12, B_Q14, | ||
159 | AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ], Lambda_Q10, | ||
160 | offset_Q10, psEncC->subfr_length, psEncC->shapingLPCOrder, psEncC->predictLPCOrder, psEncC->arch ); | ||
161 | |||
162 | x16 += psEncC->subfr_length; | ||
163 | pulses += psEncC->subfr_length; | ||
164 | pxq += psEncC->subfr_length; | ||
165 | } | ||
166 | |||
167 | /* Update lagPrev for next frame */ | ||
168 | NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ]; | ||
169 | |||
170 | /* Save quantized speech and noise shaping signals */ | ||
171 | silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) ); | ||
172 | silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) ); | ||
173 | RESTORE_STACK; | ||
174 | } | ||
175 | |||
176 | /***********************************/ | ||
177 | /* silk_noise_shape_quantizer */ | ||
178 | /***********************************/ | ||
179 | |||
180 | #if !defined(OPUS_X86_MAY_HAVE_SSE4_1) | ||
181 | static OPUS_INLINE | ||
182 | #endif | ||
183 | void silk_noise_shape_quantizer( | ||
184 | silk_nsq_state *NSQ, /* I/O NSQ state */ | ||
185 | opus_int signalType, /* I Signal type */ | ||
186 | const opus_int32 x_sc_Q10[], /* I */ | ||
187 | opus_int8 pulses[], /* O */ | ||
188 | opus_int16 xq[], /* O */ | ||
189 | opus_int32 sLTP_Q15[], /* I/O LTP state */ | ||
190 | const opus_int16 a_Q12[], /* I Short term prediction coefs */ | ||
191 | const opus_int16 b_Q14[], /* I Long term prediction coefs */ | ||
192 | const opus_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */ | ||
193 | opus_int lag, /* I Pitch lag */ | ||
194 | opus_int32 HarmShapeFIRPacked_Q14, /* I */ | ||
195 | opus_int Tilt_Q14, /* I Spectral tilt */ | ||
196 | opus_int32 LF_shp_Q14, /* I */ | ||
197 | opus_int32 Gain_Q16, /* I */ | ||
198 | opus_int Lambda_Q10, /* I */ | ||
199 | opus_int offset_Q10, /* I */ | ||
200 | opus_int length, /* I Input length */ | ||
201 | opus_int shapingLPCOrder, /* I Noise shaping AR filter order */ | ||
202 | opus_int predictLPCOrder, /* I Prediction filter order */ | ||
203 | int arch /* I Architecture */ | ||
204 | ) | ||
205 | { | ||
206 | opus_int i; | ||
207 | opus_int32 LTP_pred_Q13, LPC_pred_Q10, n_AR_Q12, n_LTP_Q13; | ||
208 | opus_int32 n_LF_Q12, r_Q10, rr_Q10, q1_Q0, q1_Q10, q2_Q10, rd1_Q20, rd2_Q20; | ||
209 | opus_int32 exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10; | ||
210 | opus_int32 tmp1, tmp2, sLF_AR_shp_Q14; | ||
211 | opus_int32 *psLPC_Q14, *shp_lag_ptr, *pred_lag_ptr; | ||
212 | #ifdef silk_short_prediction_create_arch_coef | ||
213 | opus_int32 a_Q12_arch[MAX_LPC_ORDER]; | ||
214 | #endif | ||
215 | |||
216 | shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ]; | ||
217 | pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ]; | ||
218 | Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 ); | ||
219 | |||
220 | /* Set up short term AR state */ | ||
221 | psLPC_Q14 = &NSQ->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 ]; | ||
222 | |||
223 | #ifdef silk_short_prediction_create_arch_coef | ||
224 | silk_short_prediction_create_arch_coef(a_Q12_arch, a_Q12, predictLPCOrder); | ||
225 | #endif | ||
226 | |||
227 | for( i = 0; i < length; i++ ) { | ||
228 | /* Generate dither */ | ||
229 | NSQ->rand_seed = silk_RAND( NSQ->rand_seed ); | ||
230 | |||
231 | /* Short-term prediction */ | ||
232 | LPC_pred_Q10 = silk_noise_shape_quantizer_short_prediction(psLPC_Q14, a_Q12, a_Q12_arch, predictLPCOrder, arch); | ||
233 | |||
234 | /* Long-term prediction */ | ||
235 | if( signalType == TYPE_VOICED ) { | ||
236 | /* Unrolled loop */ | ||
237 | /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ | ||
238 | LTP_pred_Q13 = 2; | ||
239 | LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ 0 ], b_Q14[ 0 ] ); | ||
240 | LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -1 ], b_Q14[ 1 ] ); | ||
241 | LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -2 ], b_Q14[ 2 ] ); | ||
242 | LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -3 ], b_Q14[ 3 ] ); | ||
243 | LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -4 ], b_Q14[ 4 ] ); | ||
244 | pred_lag_ptr++; | ||
245 | } else { | ||
246 | LTP_pred_Q13 = 0; | ||
247 | } | ||
248 | |||
249 | /* Noise shape feedback */ | ||
250 | celt_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */ | ||
251 | n_AR_Q12 = silk_NSQ_noise_shape_feedback_loop(&NSQ->sDiff_shp_Q14, NSQ->sAR2_Q14, AR_shp_Q13, shapingLPCOrder, arch); | ||
252 | |||
253 | n_AR_Q12 = silk_SMLAWB( n_AR_Q12, NSQ->sLF_AR_shp_Q14, Tilt_Q14 ); | ||
254 | |||
255 | n_LF_Q12 = silk_SMULWB( NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - 1 ], LF_shp_Q14 ); | ||
256 | n_LF_Q12 = silk_SMLAWT( n_LF_Q12, NSQ->sLF_AR_shp_Q14, LF_shp_Q14 ); | ||
257 | |||
258 | celt_assert( lag > 0 || signalType != TYPE_VOICED ); | ||
259 | |||
260 | /* Combine prediction and noise shaping signals */ | ||
261 | tmp1 = silk_SUB32( silk_LSHIFT32( LPC_pred_Q10, 2 ), n_AR_Q12 ); /* Q12 */ | ||
262 | tmp1 = silk_SUB32( tmp1, n_LF_Q12 ); /* Q12 */ | ||
263 | if( lag > 0 ) { | ||
264 | /* Symmetric, packed FIR coefficients */ | ||
265 | n_LTP_Q13 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 ); | ||
266 | n_LTP_Q13 = silk_SMLAWT( n_LTP_Q13, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 ); | ||
267 | n_LTP_Q13 = silk_LSHIFT( n_LTP_Q13, 1 ); | ||
268 | shp_lag_ptr++; | ||
269 | |||
270 | tmp2 = silk_SUB32( LTP_pred_Q13, n_LTP_Q13 ); /* Q13 */ | ||
271 | tmp1 = silk_ADD_LSHIFT32( tmp2, tmp1, 1 ); /* Q13 */ | ||
272 | tmp1 = silk_RSHIFT_ROUND( tmp1, 3 ); /* Q10 */ | ||
273 | } else { | ||
274 | tmp1 = silk_RSHIFT_ROUND( tmp1, 2 ); /* Q10 */ | ||
275 | } | ||
276 | |||
277 | r_Q10 = silk_SUB32( x_sc_Q10[ i ], tmp1 ); /* residual error Q10 */ | ||
278 | |||
279 | /* Flip sign depending on dither */ | ||
280 | if( NSQ->rand_seed < 0 ) { | ||
281 | r_Q10 = -r_Q10; | ||
282 | } | ||
283 | r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 ); | ||
284 | |||
285 | /* Find two quantization level candidates and measure their rate-distortion */ | ||
286 | q1_Q10 = silk_SUB32( r_Q10, offset_Q10 ); | ||
287 | q1_Q0 = silk_RSHIFT( q1_Q10, 10 ); | ||
288 | if (Lambda_Q10 > 2048) { | ||
289 | /* For aggressive RDO, the bias becomes more than one pulse. */ | ||
290 | int rdo_offset = Lambda_Q10/2 - 512; | ||
291 | if (q1_Q10 > rdo_offset) { | ||
292 | q1_Q0 = silk_RSHIFT( q1_Q10 - rdo_offset, 10 ); | ||
293 | } else if (q1_Q10 < -rdo_offset) { | ||
294 | q1_Q0 = silk_RSHIFT( q1_Q10 + rdo_offset, 10 ); | ||
295 | } else if (q1_Q10 < 0) { | ||
296 | q1_Q0 = -1; | ||
297 | } else { | ||
298 | q1_Q0 = 0; | ||
299 | } | ||
300 | } | ||
301 | if( q1_Q0 > 0 ) { | ||
302 | q1_Q10 = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 ); | ||
303 | q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 ); | ||
304 | q2_Q10 = silk_ADD32( q1_Q10, 1024 ); | ||
305 | rd1_Q20 = silk_SMULBB( q1_Q10, Lambda_Q10 ); | ||
306 | rd2_Q20 = silk_SMULBB( q2_Q10, Lambda_Q10 ); | ||
307 | } else if( q1_Q0 == 0 ) { | ||
308 | q1_Q10 = offset_Q10; | ||
309 | q2_Q10 = silk_ADD32( q1_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 ); | ||
310 | rd1_Q20 = silk_SMULBB( q1_Q10, Lambda_Q10 ); | ||
311 | rd2_Q20 = silk_SMULBB( q2_Q10, Lambda_Q10 ); | ||
312 | } else if( q1_Q0 == -1 ) { | ||
313 | q2_Q10 = offset_Q10; | ||
314 | q1_Q10 = silk_SUB32( q2_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 ); | ||
315 | rd1_Q20 = silk_SMULBB( -q1_Q10, Lambda_Q10 ); | ||
316 | rd2_Q20 = silk_SMULBB( q2_Q10, Lambda_Q10 ); | ||
317 | } else { /* Q1_Q0 < -1 */ | ||
318 | q1_Q10 = silk_ADD32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 ); | ||
319 | q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 ); | ||
320 | q2_Q10 = silk_ADD32( q1_Q10, 1024 ); | ||
321 | rd1_Q20 = silk_SMULBB( -q1_Q10, Lambda_Q10 ); | ||
322 | rd2_Q20 = silk_SMULBB( -q2_Q10, Lambda_Q10 ); | ||
323 | } | ||
324 | rr_Q10 = silk_SUB32( r_Q10, q1_Q10 ); | ||
325 | rd1_Q20 = silk_SMLABB( rd1_Q20, rr_Q10, rr_Q10 ); | ||
326 | rr_Q10 = silk_SUB32( r_Q10, q2_Q10 ); | ||
327 | rd2_Q20 = silk_SMLABB( rd2_Q20, rr_Q10, rr_Q10 ); | ||
328 | |||
329 | if( rd2_Q20 < rd1_Q20 ) { | ||
330 | q1_Q10 = q2_Q10; | ||
331 | } | ||
332 | |||
333 | pulses[ i ] = (opus_int8)silk_RSHIFT_ROUND( q1_Q10, 10 ); | ||
334 | |||
335 | /* Excitation */ | ||
336 | exc_Q14 = silk_LSHIFT( q1_Q10, 4 ); | ||
337 | if ( NSQ->rand_seed < 0 ) { | ||
338 | exc_Q14 = -exc_Q14; | ||
339 | } | ||
340 | |||
341 | /* Add predictions */ | ||
342 | LPC_exc_Q14 = silk_ADD_LSHIFT32( exc_Q14, LTP_pred_Q13, 1 ); | ||
343 | xq_Q14 = silk_ADD_LSHIFT32( LPC_exc_Q14, LPC_pred_Q10, 4 ); | ||
344 | |||
345 | /* Scale XQ back to normal level before saving */ | ||
346 | xq[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( xq_Q14, Gain_Q10 ), 8 ) ); | ||
347 | |||
348 | /* Update states */ | ||
349 | psLPC_Q14++; | ||
350 | *psLPC_Q14 = xq_Q14; | ||
351 | NSQ->sDiff_shp_Q14 = silk_SUB_LSHIFT32( xq_Q14, x_sc_Q10[ i ], 4 ); | ||
352 | sLF_AR_shp_Q14 = silk_SUB_LSHIFT32( NSQ->sDiff_shp_Q14, n_AR_Q12, 2 ); | ||
353 | NSQ->sLF_AR_shp_Q14 = sLF_AR_shp_Q14; | ||
354 | |||
355 | NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx ] = silk_SUB_LSHIFT32( sLF_AR_shp_Q14, n_LF_Q12, 2 ); | ||
356 | sLTP_Q15[ NSQ->sLTP_buf_idx ] = silk_LSHIFT( LPC_exc_Q14, 1 ); | ||
357 | NSQ->sLTP_shp_buf_idx++; | ||
358 | NSQ->sLTP_buf_idx++; | ||
359 | |||
360 | /* Make dither dependent on quantized signal */ | ||
361 | NSQ->rand_seed = silk_ADD32_ovflw( NSQ->rand_seed, pulses[ i ] ); | ||
362 | } | ||
363 | |||
364 | /* Update LPC synth buffer */ | ||
365 | silk_memcpy( NSQ->sLPC_Q14, &NSQ->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) ); | ||
366 | } | ||
367 | |||
368 | static OPUS_INLINE void silk_nsq_scale_states( | ||
369 | const silk_encoder_state *psEncC, /* I Encoder State */ | ||
370 | silk_nsq_state *NSQ, /* I/O NSQ state */ | ||
371 | const opus_int16 x16[], /* I input */ | ||
372 | opus_int32 x_sc_Q10[], /* O input scaled with 1/Gain */ | ||
373 | const opus_int16 sLTP[], /* I re-whitened LTP state in Q0 */ | ||
374 | opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ | ||
375 | opus_int subfr, /* I subframe number */ | ||
376 | const opus_int LTP_scale_Q14, /* I */ | ||
377 | const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ | ||
378 | const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */ | ||
379 | const opus_int signal_type /* I Signal type */ | ||
380 | ) | ||
381 | { | ||
382 | opus_int i, lag; | ||
383 | opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q26; | ||
384 | |||
385 | lag = pitchL[ subfr ]; | ||
386 | inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 ); | ||
387 | silk_assert( inv_gain_Q31 != 0 ); | ||
388 | |||
389 | /* Scale input */ | ||
390 | inv_gain_Q26 = silk_RSHIFT_ROUND( inv_gain_Q31, 5 ); | ||
391 | for( i = 0; i < psEncC->subfr_length; i++ ) { | ||
392 | x_sc_Q10[ i ] = silk_SMULWW( x16[ i ], inv_gain_Q26 ); | ||
393 | } | ||
394 | |||
395 | /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */ | ||
396 | if( NSQ->rewhite_flag ) { | ||
397 | if( subfr == 0 ) { | ||
398 | /* Do LTP downscaling */ | ||
399 | inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 ); | ||
400 | } | ||
401 | for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) { | ||
402 | silk_assert( i < MAX_FRAME_LENGTH ); | ||
403 | sLTP_Q15[ i ] = silk_SMULWB( inv_gain_Q31, sLTP[ i ] ); | ||
404 | } | ||
405 | } | ||
406 | |||
407 | /* Adjust for changing gain */ | ||
408 | if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) { | ||
409 | gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 ); | ||
410 | |||
411 | /* Scale long-term shaping state */ | ||
412 | for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx; i++ ) { | ||
413 | NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] ); | ||
414 | } | ||
415 | |||
416 | /* Scale long-term prediction state */ | ||
417 | if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) { | ||
418 | for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) { | ||
419 | sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] ); | ||
420 | } | ||
421 | } | ||
422 | |||
423 | NSQ->sLF_AR_shp_Q14 = silk_SMULWW( gain_adj_Q16, NSQ->sLF_AR_shp_Q14 ); | ||
424 | NSQ->sDiff_shp_Q14 = silk_SMULWW( gain_adj_Q16, NSQ->sDiff_shp_Q14 ); | ||
425 | |||
426 | /* Scale short-term prediction and shaping states */ | ||
427 | for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) { | ||
428 | NSQ->sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLPC_Q14[ i ] ); | ||
429 | } | ||
430 | for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) { | ||
431 | NSQ->sAR2_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sAR2_Q14[ i ] ); | ||
432 | } | ||
433 | |||
434 | /* Save inverse gain */ | ||
435 | NSQ->prev_gain_Q16 = Gains_Q16[ subfr ]; | ||
436 | } | ||
437 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/NSQ.h b/lib/rbcodec/codecs/libopus/silk/NSQ.h new file mode 100644 index 0000000000..971832f660 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/NSQ.h | |||
@@ -0,0 +1,101 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2014 Vidyo. | ||
3 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
4 | Redistribution and use in source and binary forms, with or without | ||
5 | modification, are permitted provided that the following conditions | ||
6 | are met: | ||
7 | - Redistributions of source code must retain the above copyright notice, | ||
8 | this list of conditions and the following disclaimer. | ||
9 | - Redistributions in binary form must reproduce the above copyright | ||
10 | notice, this list of conditions and the following disclaimer in the | ||
11 | documentation and/or other materials provided with the distribution. | ||
12 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
13 | names of specific contributors, may be used to endorse or promote | ||
14 | products derived from this software without specific prior written | ||
15 | permission. | ||
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
19 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
20 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
21 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
22 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
23 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
24 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
25 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
26 | POSSIBILITY OF SUCH DAMAGE. | ||
27 | ***********************************************************************/ | ||
28 | #ifndef SILK_NSQ_H | ||
29 | #define SILK_NSQ_H | ||
30 | |||
31 | #include "SigProc_FIX.h" | ||
32 | |||
33 | #undef silk_short_prediction_create_arch_coef | ||
34 | |||
35 | static OPUS_INLINE opus_int32 silk_noise_shape_quantizer_short_prediction_c(const opus_int32 *buf32, const opus_int16 *coef16, opus_int order) | ||
36 | { | ||
37 | opus_int32 out; | ||
38 | silk_assert( order == 10 || order == 16 ); | ||
39 | |||
40 | /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ | ||
41 | out = silk_RSHIFT( order, 1 ); | ||
42 | out = silk_SMLAWB( out, buf32[ 0 ], coef16[ 0 ] ); | ||
43 | out = silk_SMLAWB( out, buf32[ -1 ], coef16[ 1 ] ); | ||
44 | out = silk_SMLAWB( out, buf32[ -2 ], coef16[ 2 ] ); | ||
45 | out = silk_SMLAWB( out, buf32[ -3 ], coef16[ 3 ] ); | ||
46 | out = silk_SMLAWB( out, buf32[ -4 ], coef16[ 4 ] ); | ||
47 | out = silk_SMLAWB( out, buf32[ -5 ], coef16[ 5 ] ); | ||
48 | out = silk_SMLAWB( out, buf32[ -6 ], coef16[ 6 ] ); | ||
49 | out = silk_SMLAWB( out, buf32[ -7 ], coef16[ 7 ] ); | ||
50 | out = silk_SMLAWB( out, buf32[ -8 ], coef16[ 8 ] ); | ||
51 | out = silk_SMLAWB( out, buf32[ -9 ], coef16[ 9 ] ); | ||
52 | |||
53 | if( order == 16 ) | ||
54 | { | ||
55 | out = silk_SMLAWB( out, buf32[ -10 ], coef16[ 10 ] ); | ||
56 | out = silk_SMLAWB( out, buf32[ -11 ], coef16[ 11 ] ); | ||
57 | out = silk_SMLAWB( out, buf32[ -12 ], coef16[ 12 ] ); | ||
58 | out = silk_SMLAWB( out, buf32[ -13 ], coef16[ 13 ] ); | ||
59 | out = silk_SMLAWB( out, buf32[ -14 ], coef16[ 14 ] ); | ||
60 | out = silk_SMLAWB( out, buf32[ -15 ], coef16[ 15 ] ); | ||
61 | } | ||
62 | return out; | ||
63 | } | ||
64 | |||
65 | #define silk_noise_shape_quantizer_short_prediction(in, coef, coefRev, order, arch) ((void)arch,silk_noise_shape_quantizer_short_prediction_c(in, coef, order)) | ||
66 | |||
67 | static OPUS_INLINE opus_int32 silk_NSQ_noise_shape_feedback_loop_c(const opus_int32 *data0, opus_int32 *data1, const opus_int16 *coef, opus_int order) | ||
68 | { | ||
69 | opus_int32 out; | ||
70 | opus_int32 tmp1, tmp2; | ||
71 | opus_int j; | ||
72 | |||
73 | tmp2 = data0[0]; | ||
74 | tmp1 = data1[0]; | ||
75 | data1[0] = tmp2; | ||
76 | |||
77 | out = silk_RSHIFT(order, 1); | ||
78 | out = silk_SMLAWB(out, tmp2, coef[0]); | ||
79 | |||
80 | for (j = 2; j < order; j += 2) { | ||
81 | tmp2 = data1[j - 1]; | ||
82 | data1[j - 1] = tmp1; | ||
83 | out = silk_SMLAWB(out, tmp1, coef[j - 1]); | ||
84 | tmp1 = data1[j + 0]; | ||
85 | data1[j + 0] = tmp2; | ||
86 | out = silk_SMLAWB(out, tmp2, coef[j]); | ||
87 | } | ||
88 | data1[order - 1] = tmp1; | ||
89 | out = silk_SMLAWB(out, tmp1, coef[order - 1]); | ||
90 | /* Q11 -> Q12 */ | ||
91 | out = silk_LSHIFT32( out, 1 ); | ||
92 | return out; | ||
93 | } | ||
94 | |||
95 | #define silk_NSQ_noise_shape_feedback_loop(data0, data1, coef, order, arch) ((void)arch,silk_NSQ_noise_shape_feedback_loop_c(data0, data1, coef, order)) | ||
96 | |||
97 | #if defined(OPUS_ARM_MAY_HAVE_NEON_INTR) | ||
98 | #include "arm/NSQ_neon.h" | ||
99 | #endif | ||
100 | |||
101 | #endif /* SILK_NSQ_H */ | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/NSQ_del_dec.c b/lib/rbcodec/codecs/libopus/silk/NSQ_del_dec.c new file mode 100644 index 0000000000..3fd9fa0d5b --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/NSQ_del_dec.c | |||
@@ -0,0 +1,733 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main.h" | ||
33 | #include "stack_alloc.h" | ||
34 | #include "NSQ.h" | ||
35 | |||
36 | |||
37 | typedef struct { | ||
38 | opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH ]; | ||
39 | opus_int32 RandState[ DECISION_DELAY ]; | ||
40 | opus_int32 Q_Q10[ DECISION_DELAY ]; | ||
41 | opus_int32 Xq_Q14[ DECISION_DELAY ]; | ||
42 | opus_int32 Pred_Q15[ DECISION_DELAY ]; | ||
43 | opus_int32 Shape_Q14[ DECISION_DELAY ]; | ||
44 | opus_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ]; | ||
45 | opus_int32 LF_AR_Q14; | ||
46 | opus_int32 Diff_Q14; | ||
47 | opus_int32 Seed; | ||
48 | opus_int32 SeedInit; | ||
49 | opus_int32 RD_Q10; | ||
50 | } NSQ_del_dec_struct; | ||
51 | |||
52 | typedef struct { | ||
53 | opus_int32 Q_Q10; | ||
54 | opus_int32 RD_Q10; | ||
55 | opus_int32 xq_Q14; | ||
56 | opus_int32 LF_AR_Q14; | ||
57 | opus_int32 Diff_Q14; | ||
58 | opus_int32 sLTP_shp_Q14; | ||
59 | opus_int32 LPC_exc_Q14; | ||
60 | } NSQ_sample_struct; | ||
61 | |||
62 | typedef NSQ_sample_struct NSQ_sample_pair[ 2 ]; | ||
63 | |||
64 | #if defined(MIPSr1_ASM) | ||
65 | #include "mips/NSQ_del_dec_mipsr1.h" | ||
66 | #endif | ||
67 | static OPUS_INLINE void silk_nsq_del_dec_scale_states( | ||
68 | const silk_encoder_state *psEncC, /* I Encoder State */ | ||
69 | silk_nsq_state *NSQ, /* I/O NSQ state */ | ||
70 | NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ | ||
71 | const opus_int16 x16[], /* I Input */ | ||
72 | opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */ | ||
73 | const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */ | ||
74 | opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ | ||
75 | opus_int subfr, /* I Subframe number */ | ||
76 | opus_int nStatesDelayedDecision, /* I Number of del dec states */ | ||
77 | const opus_int LTP_scale_Q14, /* I LTP state scaling */ | ||
78 | const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ | ||
79 | const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */ | ||
80 | const opus_int signal_type, /* I Signal type */ | ||
81 | const opus_int decisionDelay /* I Decision delay */ | ||
82 | ); | ||
83 | |||
84 | /******************************************/ | ||
85 | /* Noise shape quantizer for one subframe */ | ||
86 | /******************************************/ | ||
87 | static OPUS_INLINE void silk_noise_shape_quantizer_del_dec( | ||
88 | silk_nsq_state *NSQ, /* I/O NSQ state */ | ||
89 | NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ | ||
90 | opus_int signalType, /* I Signal type */ | ||
91 | const opus_int32 x_Q10[], /* I */ | ||
92 | opus_int8 pulses[], /* O */ | ||
93 | opus_int16 xq[], /* O */ | ||
94 | opus_int32 sLTP_Q15[], /* I/O LTP filter state */ | ||
95 | opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */ | ||
96 | const opus_int16 a_Q12[], /* I Short term prediction coefs */ | ||
97 | const opus_int16 b_Q14[], /* I Long term prediction coefs */ | ||
98 | const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */ | ||
99 | opus_int lag, /* I Pitch lag */ | ||
100 | opus_int32 HarmShapeFIRPacked_Q14, /* I */ | ||
101 | opus_int Tilt_Q14, /* I Spectral tilt */ | ||
102 | opus_int32 LF_shp_Q14, /* I */ | ||
103 | opus_int32 Gain_Q16, /* I */ | ||
104 | opus_int Lambda_Q10, /* I */ | ||
105 | opus_int offset_Q10, /* I */ | ||
106 | opus_int length, /* I Input length */ | ||
107 | opus_int subfr, /* I Subframe number */ | ||
108 | opus_int shapingLPCOrder, /* I Shaping LPC filter order */ | ||
109 | opus_int predictLPCOrder, /* I Prediction filter order */ | ||
110 | opus_int warping_Q16, /* I */ | ||
111 | opus_int nStatesDelayedDecision, /* I Number of states in decision tree */ | ||
112 | opus_int *smpl_buf_idx, /* I/O Index to newest samples in buffers */ | ||
113 | opus_int decisionDelay, /* I */ | ||
114 | int arch /* I */ | ||
115 | ); | ||
116 | |||
117 | void silk_NSQ_del_dec_c( | ||
118 | const silk_encoder_state *psEncC, /* I Encoder State */ | ||
119 | silk_nsq_state *NSQ, /* I/O NSQ state */ | ||
120 | SideInfoIndices *psIndices, /* I/O Quantization Indices */ | ||
121 | const opus_int16 x16[], /* I Input */ | ||
122 | opus_int8 pulses[], /* O Quantized pulse signal */ | ||
123 | const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ | ||
124 | const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ | ||
125 | const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ | ||
126 | const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ | ||
127 | const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ | ||
128 | const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ | ||
129 | const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ | ||
130 | const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ | ||
131 | const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ | ||
132 | const opus_int LTP_scale_Q14 /* I LTP state scaling */ | ||
133 | ) | ||
134 | { | ||
135 | opus_int i, k, lag, start_idx, LSF_interpolation_flag, Winner_ind, subfr; | ||
136 | opus_int last_smple_idx, smpl_buf_idx, decisionDelay; | ||
137 | const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13; | ||
138 | opus_int16 *pxq; | ||
139 | VARDECL( opus_int32, sLTP_Q15 ); | ||
140 | VARDECL( opus_int16, sLTP ); | ||
141 | opus_int32 HarmShapeFIRPacked_Q14; | ||
142 | opus_int offset_Q10; | ||
143 | opus_int32 RDmin_Q10, Gain_Q10; | ||
144 | VARDECL( opus_int32, x_sc_Q10 ); | ||
145 | VARDECL( opus_int32, delayedGain_Q10 ); | ||
146 | VARDECL( NSQ_del_dec_struct, psDelDec ); | ||
147 | NSQ_del_dec_struct *psDD; | ||
148 | SAVE_STACK; | ||
149 | |||
150 | /* Set unvoiced lag to the previous one, overwrite later for voiced */ | ||
151 | lag = NSQ->lagPrev; | ||
152 | |||
153 | silk_assert( NSQ->prev_gain_Q16 != 0 ); | ||
154 | |||
155 | /* Initialize delayed decision states */ | ||
156 | ALLOC( psDelDec, psEncC->nStatesDelayedDecision, NSQ_del_dec_struct ); | ||
157 | silk_memset( psDelDec, 0, psEncC->nStatesDelayedDecision * sizeof( NSQ_del_dec_struct ) ); | ||
158 | for( k = 0; k < psEncC->nStatesDelayedDecision; k++ ) { | ||
159 | psDD = &psDelDec[ k ]; | ||
160 | psDD->Seed = ( k + psIndices->Seed ) & 3; | ||
161 | psDD->SeedInit = psDD->Seed; | ||
162 | psDD->RD_Q10 = 0; | ||
163 | psDD->LF_AR_Q14 = NSQ->sLF_AR_shp_Q14; | ||
164 | psDD->Diff_Q14 = NSQ->sDiff_shp_Q14; | ||
165 | psDD->Shape_Q14[ 0 ] = NSQ->sLTP_shp_Q14[ psEncC->ltp_mem_length - 1 ]; | ||
166 | silk_memcpy( psDD->sLPC_Q14, NSQ->sLPC_Q14, NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) ); | ||
167 | silk_memcpy( psDD->sAR2_Q14, NSQ->sAR2_Q14, sizeof( NSQ->sAR2_Q14 ) ); | ||
168 | } | ||
169 | |||
170 | offset_Q10 = silk_Quantization_Offsets_Q10[ psIndices->signalType >> 1 ][ psIndices->quantOffsetType ]; | ||
171 | smpl_buf_idx = 0; /* index of oldest samples */ | ||
172 | |||
173 | decisionDelay = silk_min_int( DECISION_DELAY, psEncC->subfr_length ); | ||
174 | |||
175 | /* For voiced frames limit the decision delay to lower than the pitch lag */ | ||
176 | if( psIndices->signalType == TYPE_VOICED ) { | ||
177 | for( k = 0; k < psEncC->nb_subfr; k++ ) { | ||
178 | decisionDelay = silk_min_int( decisionDelay, pitchL[ k ] - LTP_ORDER / 2 - 1 ); | ||
179 | } | ||
180 | } else { | ||
181 | if( lag > 0 ) { | ||
182 | decisionDelay = silk_min_int( decisionDelay, lag - LTP_ORDER / 2 - 1 ); | ||
183 | } | ||
184 | } | ||
185 | |||
186 | if( psIndices->NLSFInterpCoef_Q2 == 4 ) { | ||
187 | LSF_interpolation_flag = 0; | ||
188 | } else { | ||
189 | LSF_interpolation_flag = 1; | ||
190 | } | ||
191 | |||
192 | ALLOC( sLTP_Q15, psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 ); | ||
193 | ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 ); | ||
194 | ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 ); | ||
195 | ALLOC( delayedGain_Q10, DECISION_DELAY, opus_int32 ); | ||
196 | /* Set up pointers to start of sub frame */ | ||
197 | pxq = &NSQ->xq[ psEncC->ltp_mem_length ]; | ||
198 | NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length; | ||
199 | NSQ->sLTP_buf_idx = psEncC->ltp_mem_length; | ||
200 | subfr = 0; | ||
201 | for( k = 0; k < psEncC->nb_subfr; k++ ) { | ||
202 | A_Q12 = &PredCoef_Q12[ ( ( k >> 1 ) | ( 1 - LSF_interpolation_flag ) ) * MAX_LPC_ORDER ]; | ||
203 | B_Q14 = <PCoef_Q14[ k * LTP_ORDER ]; | ||
204 | AR_shp_Q13 = &AR_Q13[ k * MAX_SHAPE_LPC_ORDER ]; | ||
205 | |||
206 | /* Noise shape parameters */ | ||
207 | silk_assert( HarmShapeGain_Q14[ k ] >= 0 ); | ||
208 | HarmShapeFIRPacked_Q14 = silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 ); | ||
209 | HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 ); | ||
210 | |||
211 | NSQ->rewhite_flag = 0; | ||
212 | if( psIndices->signalType == TYPE_VOICED ) { | ||
213 | /* Voiced */ | ||
214 | lag = pitchL[ k ]; | ||
215 | |||
216 | /* Re-whitening */ | ||
217 | if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) { | ||
218 | if( k == 2 ) { | ||
219 | /* RESET DELAYED DECISIONS */ | ||
220 | /* Find winner */ | ||
221 | RDmin_Q10 = psDelDec[ 0 ].RD_Q10; | ||
222 | Winner_ind = 0; | ||
223 | for( i = 1; i < psEncC->nStatesDelayedDecision; i++ ) { | ||
224 | if( psDelDec[ i ].RD_Q10 < RDmin_Q10 ) { | ||
225 | RDmin_Q10 = psDelDec[ i ].RD_Q10; | ||
226 | Winner_ind = i; | ||
227 | } | ||
228 | } | ||
229 | for( i = 0; i < psEncC->nStatesDelayedDecision; i++ ) { | ||
230 | if( i != Winner_ind ) { | ||
231 | psDelDec[ i ].RD_Q10 += ( silk_int32_MAX >> 4 ); | ||
232 | silk_assert( psDelDec[ i ].RD_Q10 >= 0 ); | ||
233 | } | ||
234 | } | ||
235 | |||
236 | /* Copy final part of signals from winner state to output and long-term filter states */ | ||
237 | psDD = &psDelDec[ Winner_ind ]; | ||
238 | last_smple_idx = smpl_buf_idx + decisionDelay; | ||
239 | for( i = 0; i < decisionDelay; i++ ) { | ||
240 | last_smple_idx = ( last_smple_idx - 1 ) % DECISION_DELAY; | ||
241 | if( last_smple_idx < 0 ) last_smple_idx += DECISION_DELAY; | ||
242 | pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 ); | ||
243 | pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( | ||
244 | silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gains_Q16[ 1 ] ), 14 ) ); | ||
245 | NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q14[ last_smple_idx ]; | ||
246 | } | ||
247 | |||
248 | subfr = 0; | ||
249 | } | ||
250 | |||
251 | /* Rewhiten with new A coefs */ | ||
252 | start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2; | ||
253 | celt_assert( start_idx > 0 ); | ||
254 | |||
255 | silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ], | ||
256 | A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder, psEncC->arch ); | ||
257 | |||
258 | NSQ->sLTP_buf_idx = psEncC->ltp_mem_length; | ||
259 | NSQ->rewhite_flag = 1; | ||
260 | } | ||
261 | } | ||
262 | |||
263 | silk_nsq_del_dec_scale_states( psEncC, NSQ, psDelDec, x16, x_sc_Q10, sLTP, sLTP_Q15, k, | ||
264 | psEncC->nStatesDelayedDecision, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType, decisionDelay ); | ||
265 | |||
266 | silk_noise_shape_quantizer_del_dec( NSQ, psDelDec, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15, | ||
267 | delayedGain_Q10, A_Q12, B_Q14, AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], | ||
268 | Gains_Q16[ k ], Lambda_Q10, offset_Q10, psEncC->subfr_length, subfr++, psEncC->shapingLPCOrder, | ||
269 | psEncC->predictLPCOrder, psEncC->warping_Q16, psEncC->nStatesDelayedDecision, &smpl_buf_idx, decisionDelay, psEncC->arch ); | ||
270 | |||
271 | x16 += psEncC->subfr_length; | ||
272 | pulses += psEncC->subfr_length; | ||
273 | pxq += psEncC->subfr_length; | ||
274 | } | ||
275 | |||
276 | /* Find winner */ | ||
277 | RDmin_Q10 = psDelDec[ 0 ].RD_Q10; | ||
278 | Winner_ind = 0; | ||
279 | for( k = 1; k < psEncC->nStatesDelayedDecision; k++ ) { | ||
280 | if( psDelDec[ k ].RD_Q10 < RDmin_Q10 ) { | ||
281 | RDmin_Q10 = psDelDec[ k ].RD_Q10; | ||
282 | Winner_ind = k; | ||
283 | } | ||
284 | } | ||
285 | |||
286 | /* Copy final part of signals from winner state to output and long-term filter states */ | ||
287 | psDD = &psDelDec[ Winner_ind ]; | ||
288 | psIndices->Seed = psDD->SeedInit; | ||
289 | last_smple_idx = smpl_buf_idx + decisionDelay; | ||
290 | Gain_Q10 = silk_RSHIFT32( Gains_Q16[ psEncC->nb_subfr - 1 ], 6 ); | ||
291 | for( i = 0; i < decisionDelay; i++ ) { | ||
292 | last_smple_idx = ( last_smple_idx - 1 ) % DECISION_DELAY; | ||
293 | if( last_smple_idx < 0 ) last_smple_idx += DECISION_DELAY; | ||
294 | |||
295 | pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 ); | ||
296 | pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( | ||
297 | silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gain_Q10 ), 8 ) ); | ||
298 | NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q14[ last_smple_idx ]; | ||
299 | } | ||
300 | silk_memcpy( NSQ->sLPC_Q14, &psDD->sLPC_Q14[ psEncC->subfr_length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) ); | ||
301 | silk_memcpy( NSQ->sAR2_Q14, psDD->sAR2_Q14, sizeof( psDD->sAR2_Q14 ) ); | ||
302 | |||
303 | /* Update states */ | ||
304 | NSQ->sLF_AR_shp_Q14 = psDD->LF_AR_Q14; | ||
305 | NSQ->sDiff_shp_Q14 = psDD->Diff_Q14; | ||
306 | NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ]; | ||
307 | |||
308 | /* Save quantized speech signal */ | ||
309 | silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) ); | ||
310 | silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) ); | ||
311 | RESTORE_STACK; | ||
312 | } | ||
313 | |||
314 | /******************************************/ | ||
315 | /* Noise shape quantizer for one subframe */ | ||
316 | /******************************************/ | ||
317 | #ifndef OVERRIDE_silk_noise_shape_quantizer_del_dec | ||
318 | static OPUS_INLINE void silk_noise_shape_quantizer_del_dec( | ||
319 | silk_nsq_state *NSQ, /* I/O NSQ state */ | ||
320 | NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ | ||
321 | opus_int signalType, /* I Signal type */ | ||
322 | const opus_int32 x_Q10[], /* I */ | ||
323 | opus_int8 pulses[], /* O */ | ||
324 | opus_int16 xq[], /* O */ | ||
325 | opus_int32 sLTP_Q15[], /* I/O LTP filter state */ | ||
326 | opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */ | ||
327 | const opus_int16 a_Q12[], /* I Short term prediction coefs */ | ||
328 | const opus_int16 b_Q14[], /* I Long term prediction coefs */ | ||
329 | const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */ | ||
330 | opus_int lag, /* I Pitch lag */ | ||
331 | opus_int32 HarmShapeFIRPacked_Q14, /* I */ | ||
332 | opus_int Tilt_Q14, /* I Spectral tilt */ | ||
333 | opus_int32 LF_shp_Q14, /* I */ | ||
334 | opus_int32 Gain_Q16, /* I */ | ||
335 | opus_int Lambda_Q10, /* I */ | ||
336 | opus_int offset_Q10, /* I */ | ||
337 | opus_int length, /* I Input length */ | ||
338 | opus_int subfr, /* I Subframe number */ | ||
339 | opus_int shapingLPCOrder, /* I Shaping LPC filter order */ | ||
340 | opus_int predictLPCOrder, /* I Prediction filter order */ | ||
341 | opus_int warping_Q16, /* I */ | ||
342 | opus_int nStatesDelayedDecision, /* I Number of states in decision tree */ | ||
343 | opus_int *smpl_buf_idx, /* I/O Index to newest samples in buffers */ | ||
344 | opus_int decisionDelay, /* I */ | ||
345 | int arch /* I */ | ||
346 | ) | ||
347 | { | ||
348 | opus_int i, j, k, Winner_ind, RDmin_ind, RDmax_ind, last_smple_idx; | ||
349 | opus_int32 Winner_rand_state; | ||
350 | opus_int32 LTP_pred_Q14, LPC_pred_Q14, n_AR_Q14, n_LTP_Q14; | ||
351 | opus_int32 n_LF_Q14, r_Q10, rr_Q10, rd1_Q10, rd2_Q10, RDmin_Q10, RDmax_Q10; | ||
352 | opus_int32 q1_Q0, q1_Q10, q2_Q10, exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10; | ||
353 | opus_int32 tmp1, tmp2, sLF_AR_shp_Q14; | ||
354 | opus_int32 *pred_lag_ptr, *shp_lag_ptr, *psLPC_Q14; | ||
355 | #ifdef silk_short_prediction_create_arch_coef | ||
356 | opus_int32 a_Q12_arch[MAX_LPC_ORDER]; | ||
357 | #endif | ||
358 | |||
359 | VARDECL( NSQ_sample_pair, psSampleState ); | ||
360 | NSQ_del_dec_struct *psDD; | ||
361 | NSQ_sample_struct *psSS; | ||
362 | SAVE_STACK; | ||
363 | |||
364 | celt_assert( nStatesDelayedDecision > 0 ); | ||
365 | ALLOC( psSampleState, nStatesDelayedDecision, NSQ_sample_pair ); | ||
366 | |||
367 | shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ]; | ||
368 | pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ]; | ||
369 | Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 ); | ||
370 | |||
371 | #ifdef silk_short_prediction_create_arch_coef | ||
372 | silk_short_prediction_create_arch_coef(a_Q12_arch, a_Q12, predictLPCOrder); | ||
373 | #endif | ||
374 | |||
375 | for( i = 0; i < length; i++ ) { | ||
376 | /* Perform common calculations used in all states */ | ||
377 | |||
378 | /* Long-term prediction */ | ||
379 | if( signalType == TYPE_VOICED ) { | ||
380 | /* Unrolled loop */ | ||
381 | /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ | ||
382 | LTP_pred_Q14 = 2; | ||
383 | LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ 0 ], b_Q14[ 0 ] ); | ||
384 | LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -1 ], b_Q14[ 1 ] ); | ||
385 | LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -2 ], b_Q14[ 2 ] ); | ||
386 | LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -3 ], b_Q14[ 3 ] ); | ||
387 | LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], b_Q14[ 4 ] ); | ||
388 | LTP_pred_Q14 = silk_LSHIFT( LTP_pred_Q14, 1 ); /* Q13 -> Q14 */ | ||
389 | pred_lag_ptr++; | ||
390 | } else { | ||
391 | LTP_pred_Q14 = 0; | ||
392 | } | ||
393 | |||
394 | /* Long-term shaping */ | ||
395 | if( lag > 0 ) { | ||
396 | /* Symmetric, packed FIR coefficients */ | ||
397 | n_LTP_Q14 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 ); | ||
398 | n_LTP_Q14 = silk_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 ); | ||
399 | n_LTP_Q14 = silk_SUB_LSHIFT32( LTP_pred_Q14, n_LTP_Q14, 2 ); /* Q12 -> Q14 */ | ||
400 | shp_lag_ptr++; | ||
401 | } else { | ||
402 | n_LTP_Q14 = 0; | ||
403 | } | ||
404 | |||
405 | for( k = 0; k < nStatesDelayedDecision; k++ ) { | ||
406 | /* Delayed decision state */ | ||
407 | psDD = &psDelDec[ k ]; | ||
408 | |||
409 | /* Sample state */ | ||
410 | psSS = psSampleState[ k ]; | ||
411 | |||
412 | /* Generate dither */ | ||
413 | psDD->Seed = silk_RAND( psDD->Seed ); | ||
414 | |||
415 | /* Pointer used in short term prediction and shaping */ | ||
416 | psLPC_Q14 = &psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 + i ]; | ||
417 | /* Short-term prediction */ | ||
418 | LPC_pred_Q14 = silk_noise_shape_quantizer_short_prediction(psLPC_Q14, a_Q12, a_Q12_arch, predictLPCOrder, arch); | ||
419 | LPC_pred_Q14 = silk_LSHIFT( LPC_pred_Q14, 4 ); /* Q10 -> Q14 */ | ||
420 | |||
421 | /* Noise shape feedback */ | ||
422 | celt_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */ | ||
423 | /* Output of lowpass section */ | ||
424 | tmp2 = silk_SMLAWB( psDD->Diff_Q14, psDD->sAR2_Q14[ 0 ], warping_Q16 ); | ||
425 | /* Output of allpass section */ | ||
426 | tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ 0 ], psDD->sAR2_Q14[ 1 ] - tmp2, warping_Q16 ); | ||
427 | psDD->sAR2_Q14[ 0 ] = tmp2; | ||
428 | n_AR_Q14 = silk_RSHIFT( shapingLPCOrder, 1 ); | ||
429 | n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp2, AR_shp_Q13[ 0 ] ); | ||
430 | /* Loop over allpass sections */ | ||
431 | for( j = 2; j < shapingLPCOrder; j += 2 ) { | ||
432 | /* Output of allpass section */ | ||
433 | tmp2 = silk_SMLAWB( psDD->sAR2_Q14[ j - 1 ], psDD->sAR2_Q14[ j + 0 ] - tmp1, warping_Q16 ); | ||
434 | psDD->sAR2_Q14[ j - 1 ] = tmp1; | ||
435 | n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp1, AR_shp_Q13[ j - 1 ] ); | ||
436 | /* Output of allpass section */ | ||
437 | tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ j + 0 ], psDD->sAR2_Q14[ j + 1 ] - tmp2, warping_Q16 ); | ||
438 | psDD->sAR2_Q14[ j + 0 ] = tmp2; | ||
439 | n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp2, AR_shp_Q13[ j ] ); | ||
440 | } | ||
441 | psDD->sAR2_Q14[ shapingLPCOrder - 1 ] = tmp1; | ||
442 | n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp1, AR_shp_Q13[ shapingLPCOrder - 1 ] ); | ||
443 | |||
444 | n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 1 ); /* Q11 -> Q12 */ | ||
445 | n_AR_Q14 = silk_SMLAWB( n_AR_Q14, psDD->LF_AR_Q14, Tilt_Q14 ); /* Q12 */ | ||
446 | n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 2 ); /* Q12 -> Q14 */ | ||
447 | |||
448 | n_LF_Q14 = silk_SMULWB( psDD->Shape_Q14[ *smpl_buf_idx ], LF_shp_Q14 ); /* Q12 */ | ||
449 | n_LF_Q14 = silk_SMLAWT( n_LF_Q14, psDD->LF_AR_Q14, LF_shp_Q14 ); /* Q12 */ | ||
450 | n_LF_Q14 = silk_LSHIFT( n_LF_Q14, 2 ); /* Q12 -> Q14 */ | ||
451 | |||
452 | /* Input minus prediction plus noise feedback */ | ||
453 | /* r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP */ | ||
454 | tmp1 = silk_ADD32( n_AR_Q14, n_LF_Q14 ); /* Q14 */ | ||
455 | tmp2 = silk_ADD32( n_LTP_Q14, LPC_pred_Q14 ); /* Q13 */ | ||
456 | tmp1 = silk_SUB32( tmp2, tmp1 ); /* Q13 */ | ||
457 | tmp1 = silk_RSHIFT_ROUND( tmp1, 4 ); /* Q10 */ | ||
458 | |||
459 | r_Q10 = silk_SUB32( x_Q10[ i ], tmp1 ); /* residual error Q10 */ | ||
460 | |||
461 | /* Flip sign depending on dither */ | ||
462 | if ( psDD->Seed < 0 ) { | ||
463 | r_Q10 = -r_Q10; | ||
464 | } | ||
465 | r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 ); | ||
466 | |||
467 | /* Find two quantization level candidates and measure their rate-distortion */ | ||
468 | q1_Q10 = silk_SUB32( r_Q10, offset_Q10 ); | ||
469 | q1_Q0 = silk_RSHIFT( q1_Q10, 10 ); | ||
470 | if (Lambda_Q10 > 2048) { | ||
471 | /* For aggressive RDO, the bias becomes more than one pulse. */ | ||
472 | int rdo_offset = Lambda_Q10/2 - 512; | ||
473 | if (q1_Q10 > rdo_offset) { | ||
474 | q1_Q0 = silk_RSHIFT( q1_Q10 - rdo_offset, 10 ); | ||
475 | } else if (q1_Q10 < -rdo_offset) { | ||
476 | q1_Q0 = silk_RSHIFT( q1_Q10 + rdo_offset, 10 ); | ||
477 | } else if (q1_Q10 < 0) { | ||
478 | q1_Q0 = -1; | ||
479 | } else { | ||
480 | q1_Q0 = 0; | ||
481 | } | ||
482 | } | ||
483 | if( q1_Q0 > 0 ) { | ||
484 | q1_Q10 = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 ); | ||
485 | q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 ); | ||
486 | q2_Q10 = silk_ADD32( q1_Q10, 1024 ); | ||
487 | rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 ); | ||
488 | rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 ); | ||
489 | } else if( q1_Q0 == 0 ) { | ||
490 | q1_Q10 = offset_Q10; | ||
491 | q2_Q10 = silk_ADD32( q1_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 ); | ||
492 | rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 ); | ||
493 | rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 ); | ||
494 | } else if( q1_Q0 == -1 ) { | ||
495 | q2_Q10 = offset_Q10; | ||
496 | q1_Q10 = silk_SUB32( q2_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 ); | ||
497 | rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 ); | ||
498 | rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 ); | ||
499 | } else { /* q1_Q0 < -1 */ | ||
500 | q1_Q10 = silk_ADD32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 ); | ||
501 | q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 ); | ||
502 | q2_Q10 = silk_ADD32( q1_Q10, 1024 ); | ||
503 | rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 ); | ||
504 | rd2_Q10 = silk_SMULBB( -q2_Q10, Lambda_Q10 ); | ||
505 | } | ||
506 | rr_Q10 = silk_SUB32( r_Q10, q1_Q10 ); | ||
507 | rd1_Q10 = silk_RSHIFT( silk_SMLABB( rd1_Q10, rr_Q10, rr_Q10 ), 10 ); | ||
508 | rr_Q10 = silk_SUB32( r_Q10, q2_Q10 ); | ||
509 | rd2_Q10 = silk_RSHIFT( silk_SMLABB( rd2_Q10, rr_Q10, rr_Q10 ), 10 ); | ||
510 | |||
511 | if( rd1_Q10 < rd2_Q10 ) { | ||
512 | psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 ); | ||
513 | psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 ); | ||
514 | psSS[ 0 ].Q_Q10 = q1_Q10; | ||
515 | psSS[ 1 ].Q_Q10 = q2_Q10; | ||
516 | } else { | ||
517 | psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 ); | ||
518 | psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 ); | ||
519 | psSS[ 0 ].Q_Q10 = q2_Q10; | ||
520 | psSS[ 1 ].Q_Q10 = q1_Q10; | ||
521 | } | ||
522 | |||
523 | /* Update states for best quantization */ | ||
524 | |||
525 | /* Quantized excitation */ | ||
526 | exc_Q14 = silk_LSHIFT32( psSS[ 0 ].Q_Q10, 4 ); | ||
527 | if ( psDD->Seed < 0 ) { | ||
528 | exc_Q14 = -exc_Q14; | ||
529 | } | ||
530 | |||
531 | /* Add predictions */ | ||
532 | LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 ); | ||
533 | xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 ); | ||
534 | |||
535 | /* Update states */ | ||
536 | psSS[ 0 ].Diff_Q14 = silk_SUB_LSHIFT32( xq_Q14, x_Q10[ i ], 4 ); | ||
537 | sLF_AR_shp_Q14 = silk_SUB32( psSS[ 0 ].Diff_Q14, n_AR_Q14 ); | ||
538 | psSS[ 0 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 ); | ||
539 | psSS[ 0 ].LF_AR_Q14 = sLF_AR_shp_Q14; | ||
540 | psSS[ 0 ].LPC_exc_Q14 = LPC_exc_Q14; | ||
541 | psSS[ 0 ].xq_Q14 = xq_Q14; | ||
542 | |||
543 | /* Update states for second best quantization */ | ||
544 | |||
545 | /* Quantized excitation */ | ||
546 | exc_Q14 = silk_LSHIFT32( psSS[ 1 ].Q_Q10, 4 ); | ||
547 | if ( psDD->Seed < 0 ) { | ||
548 | exc_Q14 = -exc_Q14; | ||
549 | } | ||
550 | |||
551 | /* Add predictions */ | ||
552 | LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 ); | ||
553 | xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 ); | ||
554 | |||
555 | /* Update states */ | ||
556 | psSS[ 1 ].Diff_Q14 = silk_SUB_LSHIFT32( xq_Q14, x_Q10[ i ], 4 ); | ||
557 | sLF_AR_shp_Q14 = silk_SUB32( psSS[ 1 ].Diff_Q14, n_AR_Q14 ); | ||
558 | psSS[ 1 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 ); | ||
559 | psSS[ 1 ].LF_AR_Q14 = sLF_AR_shp_Q14; | ||
560 | psSS[ 1 ].LPC_exc_Q14 = LPC_exc_Q14; | ||
561 | psSS[ 1 ].xq_Q14 = xq_Q14; | ||
562 | } | ||
563 | |||
564 | *smpl_buf_idx = ( *smpl_buf_idx - 1 ) % DECISION_DELAY; | ||
565 | if( *smpl_buf_idx < 0 ) *smpl_buf_idx += DECISION_DELAY; | ||
566 | last_smple_idx = ( *smpl_buf_idx + decisionDelay ) % DECISION_DELAY; | ||
567 | |||
568 | /* Find winner */ | ||
569 | RDmin_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10; | ||
570 | Winner_ind = 0; | ||
571 | for( k = 1; k < nStatesDelayedDecision; k++ ) { | ||
572 | if( psSampleState[ k ][ 0 ].RD_Q10 < RDmin_Q10 ) { | ||
573 | RDmin_Q10 = psSampleState[ k ][ 0 ].RD_Q10; | ||
574 | Winner_ind = k; | ||
575 | } | ||
576 | } | ||
577 | |||
578 | /* Increase RD values of expired states */ | ||
579 | Winner_rand_state = psDelDec[ Winner_ind ].RandState[ last_smple_idx ]; | ||
580 | for( k = 0; k < nStatesDelayedDecision; k++ ) { | ||
581 | if( psDelDec[ k ].RandState[ last_smple_idx ] != Winner_rand_state ) { | ||
582 | psSampleState[ k ][ 0 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 0 ].RD_Q10, silk_int32_MAX >> 4 ); | ||
583 | psSampleState[ k ][ 1 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 1 ].RD_Q10, silk_int32_MAX >> 4 ); | ||
584 | silk_assert( psSampleState[ k ][ 0 ].RD_Q10 >= 0 ); | ||
585 | } | ||
586 | } | ||
587 | |||
588 | /* Find worst in first set and best in second set */ | ||
589 | RDmax_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10; | ||
590 | RDmin_Q10 = psSampleState[ 0 ][ 1 ].RD_Q10; | ||
591 | RDmax_ind = 0; | ||
592 | RDmin_ind = 0; | ||
593 | for( k = 1; k < nStatesDelayedDecision; k++ ) { | ||
594 | /* find worst in first set */ | ||
595 | if( psSampleState[ k ][ 0 ].RD_Q10 > RDmax_Q10 ) { | ||
596 | RDmax_Q10 = psSampleState[ k ][ 0 ].RD_Q10; | ||
597 | RDmax_ind = k; | ||
598 | } | ||
599 | /* find best in second set */ | ||
600 | if( psSampleState[ k ][ 1 ].RD_Q10 < RDmin_Q10 ) { | ||
601 | RDmin_Q10 = psSampleState[ k ][ 1 ].RD_Q10; | ||
602 | RDmin_ind = k; | ||
603 | } | ||
604 | } | ||
605 | |||
606 | /* Replace a state if best from second set outperforms worst in first set */ | ||
607 | if( RDmin_Q10 < RDmax_Q10 ) { | ||
608 | silk_memcpy( ( (opus_int32 *)&psDelDec[ RDmax_ind ] ) + i, | ||
609 | ( (opus_int32 *)&psDelDec[ RDmin_ind ] ) + i, sizeof( NSQ_del_dec_struct ) - i * sizeof( opus_int32) ); | ||
610 | silk_memcpy( &psSampleState[ RDmax_ind ][ 0 ], &psSampleState[ RDmin_ind ][ 1 ], sizeof( NSQ_sample_struct ) ); | ||
611 | } | ||
612 | |||
613 | /* Write samples from winner to output and long-term filter states */ | ||
614 | psDD = &psDelDec[ Winner_ind ]; | ||
615 | if( subfr > 0 || i >= decisionDelay ) { | ||
616 | pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 ); | ||
617 | xq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( | ||
618 | silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], delayedGain_Q10[ last_smple_idx ] ), 8 ) ); | ||
619 | NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay ] = psDD->Shape_Q14[ last_smple_idx ]; | ||
620 | sLTP_Q15[ NSQ->sLTP_buf_idx - decisionDelay ] = psDD->Pred_Q15[ last_smple_idx ]; | ||
621 | } | ||
622 | NSQ->sLTP_shp_buf_idx++; | ||
623 | NSQ->sLTP_buf_idx++; | ||
624 | |||
625 | /* Update states */ | ||
626 | for( k = 0; k < nStatesDelayedDecision; k++ ) { | ||
627 | psDD = &psDelDec[ k ]; | ||
628 | psSS = &psSampleState[ k ][ 0 ]; | ||
629 | psDD->LF_AR_Q14 = psSS->LF_AR_Q14; | ||
630 | psDD->Diff_Q14 = psSS->Diff_Q14; | ||
631 | psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH + i ] = psSS->xq_Q14; | ||
632 | psDD->Xq_Q14[ *smpl_buf_idx ] = psSS->xq_Q14; | ||
633 | psDD->Q_Q10[ *smpl_buf_idx ] = psSS->Q_Q10; | ||
634 | psDD->Pred_Q15[ *smpl_buf_idx ] = silk_LSHIFT32( psSS->LPC_exc_Q14, 1 ); | ||
635 | psDD->Shape_Q14[ *smpl_buf_idx ] = psSS->sLTP_shp_Q14; | ||
636 | psDD->Seed = silk_ADD32_ovflw( psDD->Seed, silk_RSHIFT_ROUND( psSS->Q_Q10, 10 ) ); | ||
637 | psDD->RandState[ *smpl_buf_idx ] = psDD->Seed; | ||
638 | psDD->RD_Q10 = psSS->RD_Q10; | ||
639 | } | ||
640 | delayedGain_Q10[ *smpl_buf_idx ] = Gain_Q10; | ||
641 | } | ||
642 | /* Update LPC states */ | ||
643 | for( k = 0; k < nStatesDelayedDecision; k++ ) { | ||
644 | psDD = &psDelDec[ k ]; | ||
645 | silk_memcpy( psDD->sLPC_Q14, &psDD->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) ); | ||
646 | } | ||
647 | RESTORE_STACK; | ||
648 | } | ||
649 | #endif /* OVERRIDE_silk_noise_shape_quantizer_del_dec */ | ||
650 | |||
651 | static OPUS_INLINE void silk_nsq_del_dec_scale_states( | ||
652 | const silk_encoder_state *psEncC, /* I Encoder State */ | ||
653 | silk_nsq_state *NSQ, /* I/O NSQ state */ | ||
654 | NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ | ||
655 | const opus_int16 x16[], /* I Input */ | ||
656 | opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */ | ||
657 | const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */ | ||
658 | opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ | ||
659 | opus_int subfr, /* I Subframe number */ | ||
660 | opus_int nStatesDelayedDecision, /* I Number of del dec states */ | ||
661 | const opus_int LTP_scale_Q14, /* I LTP state scaling */ | ||
662 | const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ | ||
663 | const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */ | ||
664 | const opus_int signal_type, /* I Signal type */ | ||
665 | const opus_int decisionDelay /* I Decision delay */ | ||
666 | ) | ||
667 | { | ||
668 | opus_int i, k, lag; | ||
669 | opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q26; | ||
670 | NSQ_del_dec_struct *psDD; | ||
671 | |||
672 | lag = pitchL[ subfr ]; | ||
673 | inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 ); | ||
674 | silk_assert( inv_gain_Q31 != 0 ); | ||
675 | |||
676 | /* Scale input */ | ||
677 | inv_gain_Q26 = silk_RSHIFT_ROUND( inv_gain_Q31, 5 ); | ||
678 | for( i = 0; i < psEncC->subfr_length; i++ ) { | ||
679 | x_sc_Q10[ i ] = silk_SMULWW( x16[ i ], inv_gain_Q26 ); | ||
680 | } | ||
681 | |||
682 | /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */ | ||
683 | if( NSQ->rewhite_flag ) { | ||
684 | if( subfr == 0 ) { | ||
685 | /* Do LTP downscaling */ | ||
686 | inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 ); | ||
687 | } | ||
688 | for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) { | ||
689 | silk_assert( i < MAX_FRAME_LENGTH ); | ||
690 | sLTP_Q15[ i ] = silk_SMULWB( inv_gain_Q31, sLTP[ i ] ); | ||
691 | } | ||
692 | } | ||
693 | |||
694 | /* Adjust for changing gain */ | ||
695 | if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) { | ||
696 | gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 ); | ||
697 | |||
698 | /* Scale long-term shaping state */ | ||
699 | for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx; i++ ) { | ||
700 | NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] ); | ||
701 | } | ||
702 | |||
703 | /* Scale long-term prediction state */ | ||
704 | if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) { | ||
705 | for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx - decisionDelay; i++ ) { | ||
706 | sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] ); | ||
707 | } | ||
708 | } | ||
709 | |||
710 | for( k = 0; k < nStatesDelayedDecision; k++ ) { | ||
711 | psDD = &psDelDec[ k ]; | ||
712 | |||
713 | /* Scale scalar states */ | ||
714 | psDD->LF_AR_Q14 = silk_SMULWW( gain_adj_Q16, psDD->LF_AR_Q14 ); | ||
715 | psDD->Diff_Q14 = silk_SMULWW( gain_adj_Q16, psDD->Diff_Q14 ); | ||
716 | |||
717 | /* Scale short-term prediction and shaping states */ | ||
718 | for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) { | ||
719 | psDD->sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->sLPC_Q14[ i ] ); | ||
720 | } | ||
721 | for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) { | ||
722 | psDD->sAR2_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->sAR2_Q14[ i ] ); | ||
723 | } | ||
724 | for( i = 0; i < DECISION_DELAY; i++ ) { | ||
725 | psDD->Pred_Q15[ i ] = silk_SMULWW( gain_adj_Q16, psDD->Pred_Q15[ i ] ); | ||
726 | psDD->Shape_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->Shape_Q14[ i ] ); | ||
727 | } | ||
728 | } | ||
729 | |||
730 | /* Save inverse gain */ | ||
731 | NSQ->prev_gain_Q16 = Gains_Q16[ subfr ]; | ||
732 | } | ||
733 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/PLC.c b/lib/rbcodec/codecs/libopus/silk/PLC.c index 8b0a8fe57d..f89391651c 100644 --- a/lib/rbcodec/codecs/libopus/silk/PLC.c +++ b/lib/rbcodec/codecs/libopus/silk/PLC.c | |||
@@ -46,7 +46,8 @@ static OPUS_INLINE void silk_PLC_update( | |||
46 | static OPUS_INLINE void silk_PLC_conceal( | 46 | static OPUS_INLINE void silk_PLC_conceal( |
47 | silk_decoder_state *psDec, /* I/O Decoder state */ | 47 | silk_decoder_state *psDec, /* I/O Decoder state */ |
48 | silk_decoder_control *psDecCtrl, /* I/O Decoder control */ | 48 | silk_decoder_control *psDecCtrl, /* I/O Decoder control */ |
49 | opus_int16 frame[] /* O LPC residual signal */ | 49 | opus_int16 frame[], /* O LPC residual signal */ |
50 | int arch /* I Run-time architecture */ | ||
50 | ); | 51 | ); |
51 | 52 | ||
52 | 53 | ||
@@ -65,7 +66,8 @@ void silk_PLC( | |||
65 | silk_decoder_state *psDec, /* I/O Decoder state */ | 66 | silk_decoder_state *psDec, /* I/O Decoder state */ |
66 | silk_decoder_control *psDecCtrl, /* I/O Decoder control */ | 67 | silk_decoder_control *psDecCtrl, /* I/O Decoder control */ |
67 | opus_int16 frame[], /* I/O signal */ | 68 | opus_int16 frame[], /* I/O signal */ |
68 | opus_int lost /* I Loss flag */ | 69 | opus_int lost, /* I Loss flag */ |
70 | int arch /* I Run-time architecture */ | ||
69 | ) | 71 | ) |
70 | { | 72 | { |
71 | /* PLC control function */ | 73 | /* PLC control function */ |
@@ -78,7 +80,7 @@ void silk_PLC( | |||
78 | /****************************/ | 80 | /****************************/ |
79 | /* Generate Signal */ | 81 | /* Generate Signal */ |
80 | /****************************/ | 82 | /****************************/ |
81 | silk_PLC_conceal( psDec, psDecCtrl, frame ); | 83 | silk_PLC_conceal( psDec, psDecCtrl, frame, arch ); |
82 | 84 | ||
83 | psDec->lossCnt++; | 85 | psDec->lossCnt++; |
84 | } else { | 86 | } else { |
@@ -192,7 +194,8 @@ static OPUS_INLINE void silk_PLC_energy(opus_int32 *energy1, opus_int *shift1, o | |||
192 | static OPUS_INLINE void silk_PLC_conceal( | 194 | static OPUS_INLINE void silk_PLC_conceal( |
193 | silk_decoder_state *psDec, /* I/O Decoder state */ | 195 | silk_decoder_state *psDec, /* I/O Decoder state */ |
194 | silk_decoder_control *psDecCtrl, /* I/O Decoder control */ | 196 | silk_decoder_control *psDecCtrl, /* I/O Decoder control */ |
195 | opus_int16 frame[] /* O LPC residual signal */ | 197 | opus_int16 frame[], /* O LPC residual signal */ |
198 | int arch /* I Run-time architecture */ | ||
196 | ) | 199 | ) |
197 | { | 200 | { |
198 | opus_int i, j, k; | 201 | opus_int i, j, k; |
@@ -272,7 +275,7 @@ static OPUS_INLINE void silk_PLC_conceal( | |||
272 | /* Reduce random noise for unvoiced frames with high LPC gain */ | 275 | /* Reduce random noise for unvoiced frames with high LPC gain */ |
273 | opus_int32 invGain_Q30, down_scale_Q30; | 276 | opus_int32 invGain_Q30, down_scale_Q30; |
274 | 277 | ||
275 | invGain_Q30 = silk_LPC_inverse_pred_gain( psPLC->prevLPC_Q12, psDec->LPC_order ); | 278 | invGain_Q30 = silk_LPC_inverse_pred_gain( psPLC->prevLPC_Q12, psDec->LPC_order, arch ); |
276 | 279 | ||
277 | down_scale_Q30 = silk_min_32( silk_RSHIFT( (opus_int32)1 << 30, LOG2_INV_LPC_GAIN_HIGH_THRES ), invGain_Q30 ); | 280 | down_scale_Q30 = silk_min_32( silk_RSHIFT( (opus_int32)1 << 30, LOG2_INV_LPC_GAIN_HIGH_THRES ), invGain_Q30 ); |
278 | down_scale_Q30 = silk_max_32( silk_RSHIFT( (opus_int32)1 << 30, LOG2_INV_LPC_GAIN_LOW_THRES ), down_scale_Q30 ); | 281 | down_scale_Q30 = silk_max_32( silk_RSHIFT( (opus_int32)1 << 30, LOG2_INV_LPC_GAIN_LOW_THRES ), down_scale_Q30 ); |
@@ -288,8 +291,8 @@ static OPUS_INLINE void silk_PLC_conceal( | |||
288 | 291 | ||
289 | /* Rewhiten LTP state */ | 292 | /* Rewhiten LTP state */ |
290 | idx = psDec->ltp_mem_length - lag - psDec->LPC_order - LTP_ORDER / 2; | 293 | idx = psDec->ltp_mem_length - lag - psDec->LPC_order - LTP_ORDER / 2; |
291 | silk_assert( idx > 0 ); | 294 | celt_assert( idx > 0 ); |
292 | silk_LPC_analysis_filter( &sLTP[ idx ], &psDec->outBuf[ idx ], A_Q12, psDec->ltp_mem_length - idx, psDec->LPC_order ); | 295 | silk_LPC_analysis_filter( &sLTP[ idx ], &psDec->outBuf[ idx ], A_Q12, psDec->ltp_mem_length - idx, psDec->LPC_order, arch ); |
293 | /* Scale LTP state */ | 296 | /* Scale LTP state */ |
294 | inv_gain_Q30 = silk_INVERSE32_varQ( psPLC->prevGain_Q16[ 1 ], 46 ); | 297 | inv_gain_Q30 = silk_INVERSE32_varQ( psPLC->prevGain_Q16[ 1 ], 46 ); |
295 | inv_gain_Q30 = silk_min( inv_gain_Q30, silk_int32_MAX >> 1 ); | 298 | inv_gain_Q30 = silk_min( inv_gain_Q30, silk_int32_MAX >> 1 ); |
@@ -325,8 +328,10 @@ static OPUS_INLINE void silk_PLC_conceal( | |||
325 | for( j = 0; j < LTP_ORDER; j++ ) { | 328 | for( j = 0; j < LTP_ORDER; j++ ) { |
326 | B_Q14[ j ] = silk_RSHIFT( silk_SMULBB( harm_Gain_Q15, B_Q14[ j ] ), 15 ); | 329 | B_Q14[ j ] = silk_RSHIFT( silk_SMULBB( harm_Gain_Q15, B_Q14[ j ] ), 15 ); |
327 | } | 330 | } |
328 | /* Gradually reduce excitation gain */ | 331 | if ( psDec->indices.signalType != TYPE_NO_VOICE_ACTIVITY ) { |
329 | rand_scale_Q14 = silk_RSHIFT( silk_SMULBB( rand_scale_Q14, rand_Gain_Q15 ), 15 ); | 332 | /* Gradually reduce excitation gain */ |
333 | rand_scale_Q14 = silk_RSHIFT( silk_SMULBB( rand_scale_Q14, rand_Gain_Q15 ), 15 ); | ||
334 | } | ||
330 | 335 | ||
331 | /* Slowly increase pitch lag */ | 336 | /* Slowly increase pitch lag */ |
332 | psPLC->pitchL_Q8 = silk_SMLAWB( psPLC->pitchL_Q8, psPLC->pitchL_Q8, PITCH_DRIFT_FAC_Q16 ); | 337 | psPLC->pitchL_Q8 = silk_SMLAWB( psPLC->pitchL_Q8, psPLC->pitchL_Q8, PITCH_DRIFT_FAC_Q16 ); |
@@ -342,7 +347,7 @@ static OPUS_INLINE void silk_PLC_conceal( | |||
342 | /* Copy LPC state */ | 347 | /* Copy LPC state */ |
343 | silk_memcpy( sLPC_Q14_ptr, psDec->sLPC_Q14_buf, MAX_LPC_ORDER * sizeof( opus_int32 ) ); | 348 | silk_memcpy( sLPC_Q14_ptr, psDec->sLPC_Q14_buf, MAX_LPC_ORDER * sizeof( opus_int32 ) ); |
344 | 349 | ||
345 | silk_assert( psDec->LPC_order >= 10 ); /* check that unrolling works */ | 350 | celt_assert( psDec->LPC_order >= 10 ); /* check that unrolling works */ |
346 | for( i = 0; i < psDec->frame_length; i++ ) { | 351 | for( i = 0; i < psDec->frame_length; i++ ) { |
347 | /* partly unrolled */ | 352 | /* partly unrolled */ |
348 | /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ | 353 | /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ |
@@ -362,7 +367,8 @@ static OPUS_INLINE void silk_PLC_conceal( | |||
362 | } | 367 | } |
363 | 368 | ||
364 | /* Add prediction to LPC excitation */ | 369 | /* Add prediction to LPC excitation */ |
365 | sLPC_Q14_ptr[ MAX_LPC_ORDER + i ] = silk_ADD_LSHIFT32( sLPC_Q14_ptr[ MAX_LPC_ORDER + i ], LPC_pred_Q10, 4 ); | 370 | sLPC_Q14_ptr[ MAX_LPC_ORDER + i ] = silk_ADD_SAT32( sLPC_Q14_ptr[ MAX_LPC_ORDER + i ], |
371 | silk_LSHIFT_SAT32( LPC_pred_Q10, 4 )); | ||
366 | 372 | ||
367 | /* Scale with Gain */ | 373 | /* Scale with Gain */ |
368 | frame[ i ] = (opus_int16)silk_SAT16( silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( sLPC_Q14_ptr[ MAX_LPC_ORDER + i ], prevGain_Q10[ 1 ] ), 8 ) ) ); | 374 | frame[ i ] = (opus_int16)silk_SAT16( silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( sLPC_Q14_ptr[ MAX_LPC_ORDER + i ], prevGain_Q10[ 1 ] ), 8 ) ) ); |
diff --git a/lib/rbcodec/codecs/libopus/silk/PLC.h b/lib/rbcodec/codecs/libopus/silk/PLC.h index f1e2eccc69..6438f51633 100644 --- a/lib/rbcodec/codecs/libopus/silk/PLC.h +++ b/lib/rbcodec/codecs/libopus/silk/PLC.h | |||
@@ -48,7 +48,8 @@ void silk_PLC( | |||
48 | silk_decoder_state *psDec, /* I/O Decoder state */ | 48 | silk_decoder_state *psDec, /* I/O Decoder state */ |
49 | silk_decoder_control *psDecCtrl, /* I/O Decoder control */ | 49 | silk_decoder_control *psDecCtrl, /* I/O Decoder control */ |
50 | opus_int16 frame[], /* I/O signal */ | 50 | opus_int16 frame[], /* I/O signal */ |
51 | opus_int lost /* I Loss flag */ | 51 | opus_int lost, /* I Loss flag */ |
52 | int arch /* I Run-time architecture */ | ||
52 | ); | 53 | ); |
53 | 54 | ||
54 | void silk_PLC_glue_frames( | 55 | void silk_PLC_glue_frames( |
diff --git a/lib/rbcodec/codecs/libopus/silk/SigProc_FIX.h b/lib/rbcodec/codecs/libopus/silk/SigProc_FIX.h index 4be0985435..f9ae326326 100644 --- a/lib/rbcodec/codecs/libopus/silk/SigProc_FIX.h +++ b/lib/rbcodec/codecs/libopus/silk/SigProc_FIX.h | |||
@@ -35,13 +35,22 @@ extern "C" | |||
35 | 35 | ||
36 | /*#define silk_MACRO_COUNT */ /* Used to enable WMOPS counting */ | 36 | /*#define silk_MACRO_COUNT */ /* Used to enable WMOPS counting */ |
37 | 37 | ||
38 | #define SILK_MAX_ORDER_LPC 16 /* max order of the LPC analysis in schur() and k2a() */ | 38 | #define SILK_MAX_ORDER_LPC 24 /* max order of the LPC analysis in schur() and k2a() */ |
39 | 39 | ||
40 | #include <string.h> /* for memset(), memcpy(), memmove() */ | 40 | #include <string.h> /* for memset(), memcpy(), memmove() */ |
41 | #include "typedef.h" | 41 | #include "typedef.h" |
42 | #include "resampler_structs.h" | 42 | #include "resampler_structs.h" |
43 | #include "macros.h" | 43 | #include "macros.h" |
44 | #include "cpu_support.h" | ||
44 | 45 | ||
46 | #if defined(OPUS_X86_MAY_HAVE_SSE4_1) | ||
47 | #include "x86/SigProc_FIX_sse.h" | ||
48 | #endif | ||
49 | |||
50 | #if (defined(OPUS_ARM_ASM) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)) | ||
51 | #include "arm/biquad_alt_arm.h" | ||
52 | #include "arm/LPC_inv_pred_gain_arm.h" | ||
53 | #endif | ||
45 | 54 | ||
46 | /********************************************************************/ | 55 | /********************************************************************/ |
47 | /* SIGNAL PROCESSING FUNCTIONS */ | 56 | /* SIGNAL PROCESSING FUNCTIONS */ |
@@ -92,14 +101,22 @@ void silk_resampler_down2_3( | |||
92 | * slower than biquad() but uses more precise coefficients | 101 | * slower than biquad() but uses more precise coefficients |
93 | * can handle (slowly) varying coefficients | 102 | * can handle (slowly) varying coefficients |
94 | */ | 103 | */ |
95 | void silk_biquad_alt( | 104 | void silk_biquad_alt_stride1( |
96 | const opus_int16 *in, /* I input signal */ | 105 | const opus_int16 *in, /* I input signal */ |
97 | const opus_int32 *B_Q28, /* I MA coefficients [3] */ | 106 | const opus_int32 *B_Q28, /* I MA coefficients [3] */ |
98 | const opus_int32 *A_Q28, /* I AR coefficients [2] */ | 107 | const opus_int32 *A_Q28, /* I AR coefficients [2] */ |
99 | opus_int32 *S, /* I/O State vector [2] */ | 108 | opus_int32 *S, /* I/O State vector [2] */ |
100 | opus_int16 *out, /* O output signal */ | 109 | opus_int16 *out, /* O output signal */ |
101 | const opus_int32 len, /* I signal length (must be even) */ | 110 | const opus_int32 len /* I signal length (must be even) */ |
102 | opus_int stride /* I Operate on interleaved signal if > 1 */ | 111 | ); |
112 | |||
113 | void silk_biquad_alt_stride2_c( | ||
114 | const opus_int16 *in, /* I input signal */ | ||
115 | const opus_int32 *B_Q28, /* I MA coefficients [3] */ | ||
116 | const opus_int32 *A_Q28, /* I AR coefficients [2] */ | ||
117 | opus_int32 *S, /* I/O State vector [4] */ | ||
118 | opus_int16 *out, /* O output signal */ | ||
119 | const opus_int32 len /* I signal length (must be even) */ | ||
103 | ); | 120 | ); |
104 | 121 | ||
105 | /* Variable order MA prediction error filter. */ | 122 | /* Variable order MA prediction error filter. */ |
@@ -108,7 +125,8 @@ void silk_LPC_analysis_filter( | |||
108 | const opus_int16 *in, /* I Input signal */ | 125 | const opus_int16 *in, /* I Input signal */ |
109 | const opus_int16 *B, /* I MA prediction coefficients, Q12 [order] */ | 126 | const opus_int16 *B, /* I MA prediction coefficients, Q12 [order] */ |
110 | const opus_int32 len, /* I Signal length */ | 127 | const opus_int32 len, /* I Signal length */ |
111 | const opus_int32 d /* I Filter order */ | 128 | const opus_int32 d, /* I Filter order */ |
129 | int arch /* I Run-time architecture */ | ||
112 | ); | 130 | ); |
113 | 131 | ||
114 | /* Chirp (bandwidth expand) LP AR filter */ | 132 | /* Chirp (bandwidth expand) LP AR filter */ |
@@ -127,17 +145,11 @@ void silk_bwexpander_32( | |||
127 | 145 | ||
128 | /* Compute inverse of LPC prediction gain, and */ | 146 | /* Compute inverse of LPC prediction gain, and */ |
129 | /* test if LPC coefficients are stable (all poles within unit circle) */ | 147 | /* test if LPC coefficients are stable (all poles within unit circle) */ |
130 | opus_int32 silk_LPC_inverse_pred_gain( /* O Returns inverse prediction gain in energy domain, Q30 */ | 148 | opus_int32 silk_LPC_inverse_pred_gain_c( /* O Returns inverse prediction gain in energy domain, Q30 */ |
131 | const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */ | 149 | const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */ |
132 | const opus_int order /* I Prediction order */ | 150 | const opus_int order /* I Prediction order */ |
133 | ); | 151 | ); |
134 | 152 | ||
135 | /* For input in Q24 domain */ | ||
136 | opus_int32 silk_LPC_inverse_pred_gain_Q24( /* O Returns inverse prediction gain in energy domain, Q30 */ | ||
137 | const opus_int32 *A_Q24, /* I Prediction coefficients [order] */ | ||
138 | const opus_int order /* I Prediction order */ | ||
139 | ); | ||
140 | |||
141 | /* Split signal in two decimated bands using first-order allpass filters */ | 153 | /* Split signal in two decimated bands using first-order allpass filters */ |
142 | void silk_ana_filt_bank_1( | 154 | void silk_ana_filt_bank_1( |
143 | const opus_int16 *in, /* I Input signal [N] */ | 155 | const opus_int16 *in, /* I Input signal [N] */ |
@@ -147,6 +159,14 @@ void silk_ana_filt_bank_1( | |||
147 | const opus_int32 N /* I Number of input samples */ | 159 | const opus_int32 N /* I Number of input samples */ |
148 | ); | 160 | ); |
149 | 161 | ||
162 | #if !defined(OVERRIDE_silk_biquad_alt_stride2) | ||
163 | #define silk_biquad_alt_stride2(in, B_Q28, A_Q28, S, out, len, arch) ((void)(arch), silk_biquad_alt_stride2_c(in, B_Q28, A_Q28, S, out, len)) | ||
164 | #endif | ||
165 | |||
166 | #if !defined(OVERRIDE_silk_LPC_inverse_pred_gain) | ||
167 | #define silk_LPC_inverse_pred_gain(A_Q12, order, arch) ((void)(arch), silk_LPC_inverse_pred_gain_c(A_Q12, order)) | ||
168 | #endif | ||
169 | |||
150 | /********************************************************************/ | 170 | /********************************************************************/ |
151 | /* SCALAR FUNCTIONS */ | 171 | /* SCALAR FUNCTIONS */ |
152 | /********************************************************************/ | 172 | /********************************************************************/ |
@@ -266,7 +286,17 @@ void silk_A2NLSF( | |||
266 | void silk_NLSF2A( | 286 | void silk_NLSF2A( |
267 | opus_int16 *a_Q12, /* O monic whitening filter coefficients in Q12, [ d ] */ | 287 | opus_int16 *a_Q12, /* O monic whitening filter coefficients in Q12, [ d ] */ |
268 | const opus_int16 *NLSF, /* I normalized line spectral frequencies in Q15, [ d ] */ | 288 | const opus_int16 *NLSF, /* I normalized line spectral frequencies in Q15, [ d ] */ |
269 | const opus_int d /* I filter order (should be even) */ | 289 | const opus_int d, /* I filter order (should be even) */ |
290 | int arch /* I Run-time architecture */ | ||
291 | ); | ||
292 | |||
293 | /* Convert int32 coefficients to int16 coefs and make sure there's no wrap-around */ | ||
294 | void silk_LPC_fit( | ||
295 | opus_int16 *a_QOUT, /* O Output signal */ | ||
296 | opus_int32 *a_QIN, /* I/O Input signal */ | ||
297 | const opus_int QOUT, /* I Input Q domain */ | ||
298 | const opus_int QIN, /* I Input Q domain */ | ||
299 | const opus_int d /* I Filter order */ | ||
270 | ); | 300 | ); |
271 | 301 | ||
272 | void silk_insertion_sort_increasing( | 302 | void silk_insertion_sort_increasing( |
@@ -303,7 +333,7 @@ void silk_NLSF_VQ_weights_laroia( | |||
303 | ); | 333 | ); |
304 | 334 | ||
305 | /* Compute reflection coefficients from input signal */ | 335 | /* Compute reflection coefficients from input signal */ |
306 | void silk_burg_modified( | 336 | void silk_burg_modified_c( |
307 | opus_int32 *res_nrg, /* O Residual energy */ | 337 | opus_int32 *res_nrg, /* O Residual energy */ |
308 | opus_int *res_nrg_Q, /* O Residual energy Q value */ | 338 | opus_int *res_nrg_Q, /* O Residual energy Q value */ |
309 | opus_int32 A_Q16[], /* O Prediction coefficients (length order) */ | 339 | opus_int32 A_Q16[], /* O Prediction coefficients (length order) */ |
@@ -335,12 +365,15 @@ void silk_scale_vector32_Q26_lshift_18( | |||
335 | /********************************************************************/ | 365 | /********************************************************************/ |
336 | 366 | ||
337 | /* return sum( inVec1[i] * inVec2[i] ) */ | 367 | /* return sum( inVec1[i] * inVec2[i] ) */ |
368 | |||
338 | opus_int32 silk_inner_prod_aligned( | 369 | opus_int32 silk_inner_prod_aligned( |
339 | const opus_int16 *const inVec1, /* I input vector 1 */ | 370 | const opus_int16 *const inVec1, /* I input vector 1 */ |
340 | const opus_int16 *const inVec2, /* I input vector 2 */ | 371 | const opus_int16 *const inVec2, /* I input vector 2 */ |
341 | const opus_int len /* I vector lengths */ | 372 | const opus_int len, /* I vector lengths */ |
373 | int arch /* I Run-time architecture */ | ||
342 | ); | 374 | ); |
343 | 375 | ||
376 | |||
344 | opus_int32 silk_inner_prod_aligned_scale( | 377 | opus_int32 silk_inner_prod_aligned_scale( |
345 | const opus_int16 *const inVec1, /* I input vector 1 */ | 378 | const opus_int16 *const inVec1, /* I input vector 1 */ |
346 | const opus_int16 *const inVec2, /* I input vector 2 */ | 379 | const opus_int16 *const inVec2, /* I input vector 2 */ |
@@ -348,7 +381,7 @@ opus_int32 silk_inner_prod_aligned_scale( | |||
348 | const opus_int len /* I vector lengths */ | 381 | const opus_int len /* I vector lengths */ |
349 | ); | 382 | ); |
350 | 383 | ||
351 | opus_int64 silk_inner_prod16_aligned_64( | 384 | opus_int64 silk_inner_prod16_aligned_64_c( |
352 | const opus_int16 *inVec1, /* I input vector 1 */ | 385 | const opus_int16 *inVec1, /* I input vector 1 */ |
353 | const opus_int16 *inVec2, /* I input vector 2 */ | 386 | const opus_int16 *inVec2, /* I input vector 2 */ |
354 | const opus_int len /* I vector lengths */ | 387 | const opus_int len /* I vector lengths */ |
@@ -463,8 +496,7 @@ static OPUS_INLINE opus_int32 silk_ROR32( opus_int32 a32, opus_int rot ) | |||
463 | /* Add with saturation for positive input values */ | 496 | /* Add with saturation for positive input values */ |
464 | #define silk_ADD_POS_SAT8(a, b) ((((a)+(b)) & 0x80) ? silk_int8_MAX : ((a)+(b))) | 497 | #define silk_ADD_POS_SAT8(a, b) ((((a)+(b)) & 0x80) ? silk_int8_MAX : ((a)+(b))) |
465 | #define silk_ADD_POS_SAT16(a, b) ((((a)+(b)) & 0x8000) ? silk_int16_MAX : ((a)+(b))) | 498 | #define silk_ADD_POS_SAT16(a, b) ((((a)+(b)) & 0x8000) ? silk_int16_MAX : ((a)+(b))) |
466 | #define silk_ADD_POS_SAT32(a, b) ((((a)+(b)) & 0x80000000) ? silk_int32_MAX : ((a)+(b))) | 499 | #define silk_ADD_POS_SAT32(a, b) ((((opus_uint32)(a)+(opus_uint32)(b)) & 0x80000000) ? silk_int32_MAX : ((a)+(b))) |
467 | #define silk_ADD_POS_SAT64(a, b) ((((a)+(b)) & 0x8000000000000000LL) ? silk_int64_MAX : ((a)+(b))) | ||
468 | 500 | ||
469 | #define silk_LSHIFT8(a, shift) ((opus_int8)((opus_uint8)(a)<<(shift))) /* shift >= 0, shift < 8 */ | 501 | #define silk_LSHIFT8(a, shift) ((opus_int8)((opus_uint8)(a)<<(shift))) /* shift >= 0, shift < 8 */ |
470 | #define silk_LSHIFT16(a, shift) ((opus_int16)((opus_uint16)(a)<<(shift))) /* shift >= 0, shift < 16 */ | 502 | #define silk_LSHIFT16(a, shift) ((opus_int16)((opus_uint16)(a)<<(shift))) /* shift >= 0, shift < 16 */ |
@@ -564,7 +596,9 @@ static OPUS_INLINE opus_int64 silk_max_64(opus_int64 a, opus_int64 b) | |||
564 | /* Make sure to store the result as the seed for the next call (also in between */ | 596 | /* Make sure to store the result as the seed for the next call (also in between */ |
565 | /* frames), otherwise result won't be random at all. When only using some of the */ | 597 | /* frames), otherwise result won't be random at all. When only using some of the */ |
566 | /* bits, take the most significant bits by right-shifting. */ | 598 | /* bits, take the most significant bits by right-shifting. */ |
567 | #define silk_RAND(seed) (silk_MLA_ovflw(907633515, (seed), 196314165)) | 599 | #define RAND_MULTIPLIER 196314165 |
600 | #define RAND_INCREMENT 907633515 | ||
601 | #define silk_RAND(seed) (silk_MLA_ovflw((RAND_INCREMENT), (seed), (RAND_MULTIPLIER))) | ||
568 | 602 | ||
569 | /* Add some multiplication functions that can be easily mapped to ARM. */ | 603 | /* Add some multiplication functions that can be easily mapped to ARM. */ |
570 | 604 | ||
@@ -575,6 +609,14 @@ static OPUS_INLINE opus_int64 silk_max_64(opus_int64 a, opus_int64 b) | |||
575 | /* the following seems faster on x86 */ | 609 | /* the following seems faster on x86 */ |
576 | #define silk_SMMUL(a32, b32) (opus_int32)silk_RSHIFT64(silk_SMULL((a32), (b32)), 32) | 610 | #define silk_SMMUL(a32, b32) (opus_int32)silk_RSHIFT64(silk_SMULL((a32), (b32)), 32) |
577 | 611 | ||
612 | #if !defined(OPUS_X86_MAY_HAVE_SSE4_1) | ||
613 | #define silk_burg_modified(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch) \ | ||
614 | ((void)(arch), silk_burg_modified_c(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch)) | ||
615 | |||
616 | #define silk_inner_prod16_aligned_64(inVec1, inVec2, len, arch) \ | ||
617 | ((void)(arch),silk_inner_prod16_aligned_64_c(inVec1, inVec2, len)) | ||
618 | #endif | ||
619 | |||
578 | #include "Inlines.h" | 620 | #include "Inlines.h" |
579 | #include "MacroCount.h" | 621 | #include "MacroCount.h" |
580 | #include "MacroDebug.h" | 622 | #include "MacroDebug.h" |
diff --git a/lib/rbcodec/codecs/libopus/silk/VAD.c b/lib/rbcodec/codecs/libopus/silk/VAD.c new file mode 100644 index 0000000000..d0cda52162 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/VAD.c | |||
@@ -0,0 +1,360 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main.h" | ||
33 | #include "stack_alloc.h" | ||
34 | |||
35 | /* Silk VAD noise level estimation */ | ||
36 | # if !defined(OPUS_X86_MAY_HAVE_SSE4_1) | ||
37 | static OPUS_INLINE void silk_VAD_GetNoiseLevels( | ||
38 | const opus_int32 pX[ VAD_N_BANDS ], /* I subband energies */ | ||
39 | silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */ | ||
40 | ); | ||
41 | #endif | ||
42 | |||
43 | /**********************************/ | ||
44 | /* Initialization of the Silk VAD */ | ||
45 | /**********************************/ | ||
46 | opus_int silk_VAD_Init( /* O Return value, 0 if success */ | ||
47 | silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */ | ||
48 | ) | ||
49 | { | ||
50 | opus_int b, ret = 0; | ||
51 | |||
52 | /* reset state memory */ | ||
53 | silk_memset( psSilk_VAD, 0, sizeof( silk_VAD_state ) ); | ||
54 | |||
55 | /* init noise levels */ | ||
56 | /* Initialize array with approx pink noise levels (psd proportional to inverse of frequency) */ | ||
57 | for( b = 0; b < VAD_N_BANDS; b++ ) { | ||
58 | psSilk_VAD->NoiseLevelBias[ b ] = silk_max_32( silk_DIV32_16( VAD_NOISE_LEVELS_BIAS, b + 1 ), 1 ); | ||
59 | } | ||
60 | |||
61 | /* Initialize state */ | ||
62 | for( b = 0; b < VAD_N_BANDS; b++ ) { | ||
63 | psSilk_VAD->NL[ b ] = silk_MUL( 100, psSilk_VAD->NoiseLevelBias[ b ] ); | ||
64 | psSilk_VAD->inv_NL[ b ] = silk_DIV32( silk_int32_MAX, psSilk_VAD->NL[ b ] ); | ||
65 | } | ||
66 | psSilk_VAD->counter = 15; | ||
67 | |||
68 | /* init smoothed energy-to-noise ratio*/ | ||
69 | for( b = 0; b < VAD_N_BANDS; b++ ) { | ||
70 | psSilk_VAD->NrgRatioSmth_Q8[ b ] = 100 * 256; /* 100 * 256 --> 20 dB SNR */ | ||
71 | } | ||
72 | |||
73 | return( ret ); | ||
74 | } | ||
75 | |||
76 | /* Weighting factors for tilt measure */ | ||
77 | static const opus_int32 tiltWeights[ VAD_N_BANDS ] = { 30000, 6000, -12000, -12000 }; | ||
78 | |||
79 | /***************************************/ | ||
80 | /* Get the speech activity level in Q8 */ | ||
81 | /***************************************/ | ||
82 | opus_int silk_VAD_GetSA_Q8_c( /* O Return value, 0 if success */ | ||
83 | silk_encoder_state *psEncC, /* I/O Encoder state */ | ||
84 | const opus_int16 pIn[] /* I PCM input */ | ||
85 | ) | ||
86 | { | ||
87 | opus_int SA_Q15, pSNR_dB_Q7, input_tilt; | ||
88 | opus_int decimated_framelength1, decimated_framelength2; | ||
89 | opus_int decimated_framelength; | ||
90 | opus_int dec_subframe_length, dec_subframe_offset, SNR_Q7, i, b, s; | ||
91 | opus_int32 sumSquared, smooth_coef_Q16; | ||
92 | opus_int16 HPstateTmp; | ||
93 | VARDECL( opus_int16, X ); | ||
94 | opus_int32 Xnrg[ VAD_N_BANDS ]; | ||
95 | opus_int32 NrgToNoiseRatio_Q8[ VAD_N_BANDS ]; | ||
96 | opus_int32 speech_nrg, x_tmp; | ||
97 | opus_int X_offset[ VAD_N_BANDS ]; | ||
98 | opus_int ret = 0; | ||
99 | silk_VAD_state *psSilk_VAD = &psEncC->sVAD; | ||
100 | SAVE_STACK; | ||
101 | |||
102 | /* Safety checks */ | ||
103 | silk_assert( VAD_N_BANDS == 4 ); | ||
104 | celt_assert( MAX_FRAME_LENGTH >= psEncC->frame_length ); | ||
105 | celt_assert( psEncC->frame_length <= 512 ); | ||
106 | celt_assert( psEncC->frame_length == 8 * silk_RSHIFT( psEncC->frame_length, 3 ) ); | ||
107 | |||
108 | /***********************/ | ||
109 | /* Filter and Decimate */ | ||
110 | /***********************/ | ||
111 | decimated_framelength1 = silk_RSHIFT( psEncC->frame_length, 1 ); | ||
112 | decimated_framelength2 = silk_RSHIFT( psEncC->frame_length, 2 ); | ||
113 | decimated_framelength = silk_RSHIFT( psEncC->frame_length, 3 ); | ||
114 | /* Decimate into 4 bands: | ||
115 | 0 L 3L L 3L 5L | ||
116 | - -- - -- -- | ||
117 | 8 8 2 4 4 | ||
118 | |||
119 | [0-1 kHz| temp. |1-2 kHz| 2-4 kHz | 4-8 kHz | | ||
120 | |||
121 | They're arranged to allow the minimal ( frame_length / 4 ) extra | ||
122 | scratch space during the downsampling process */ | ||
123 | X_offset[ 0 ] = 0; | ||
124 | X_offset[ 1 ] = decimated_framelength + decimated_framelength2; | ||
125 | X_offset[ 2 ] = X_offset[ 1 ] + decimated_framelength; | ||
126 | X_offset[ 3 ] = X_offset[ 2 ] + decimated_framelength2; | ||
127 | ALLOC( X, X_offset[ 3 ] + decimated_framelength1, opus_int16 ); | ||
128 | |||
129 | /* 0-8 kHz to 0-4 kHz and 4-8 kHz */ | ||
130 | silk_ana_filt_bank_1( pIn, &psSilk_VAD->AnaState[ 0 ], | ||
131 | X, &X[ X_offset[ 3 ] ], psEncC->frame_length ); | ||
132 | |||
133 | /* 0-4 kHz to 0-2 kHz and 2-4 kHz */ | ||
134 | silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState1[ 0 ], | ||
135 | X, &X[ X_offset[ 2 ] ], decimated_framelength1 ); | ||
136 | |||
137 | /* 0-2 kHz to 0-1 kHz and 1-2 kHz */ | ||
138 | silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState2[ 0 ], | ||
139 | X, &X[ X_offset[ 1 ] ], decimated_framelength2 ); | ||
140 | |||
141 | /*********************************************/ | ||
142 | /* HP filter on lowest band (differentiator) */ | ||
143 | /*********************************************/ | ||
144 | X[ decimated_framelength - 1 ] = silk_RSHIFT( X[ decimated_framelength - 1 ], 1 ); | ||
145 | HPstateTmp = X[ decimated_framelength - 1 ]; | ||
146 | for( i = decimated_framelength - 1; i > 0; i-- ) { | ||
147 | X[ i - 1 ] = silk_RSHIFT( X[ i - 1 ], 1 ); | ||
148 | X[ i ] -= X[ i - 1 ]; | ||
149 | } | ||
150 | X[ 0 ] -= psSilk_VAD->HPstate; | ||
151 | psSilk_VAD->HPstate = HPstateTmp; | ||
152 | |||
153 | /*************************************/ | ||
154 | /* Calculate the energy in each band */ | ||
155 | /*************************************/ | ||
156 | for( b = 0; b < VAD_N_BANDS; b++ ) { | ||
157 | /* Find the decimated framelength in the non-uniformly divided bands */ | ||
158 | decimated_framelength = silk_RSHIFT( psEncC->frame_length, silk_min_int( VAD_N_BANDS - b, VAD_N_BANDS - 1 ) ); | ||
159 | |||
160 | /* Split length into subframe lengths */ | ||
161 | dec_subframe_length = silk_RSHIFT( decimated_framelength, VAD_INTERNAL_SUBFRAMES_LOG2 ); | ||
162 | dec_subframe_offset = 0; | ||
163 | |||
164 | /* Compute energy per sub-frame */ | ||
165 | /* initialize with summed energy of last subframe */ | ||
166 | Xnrg[ b ] = psSilk_VAD->XnrgSubfr[ b ]; | ||
167 | for( s = 0; s < VAD_INTERNAL_SUBFRAMES; s++ ) { | ||
168 | sumSquared = 0; | ||
169 | for( i = 0; i < dec_subframe_length; i++ ) { | ||
170 | /* The energy will be less than dec_subframe_length * ( silk_int16_MIN / 8 ) ^ 2. */ | ||
171 | /* Therefore we can accumulate with no risk of overflow (unless dec_subframe_length > 128) */ | ||
172 | x_tmp = silk_RSHIFT( | ||
173 | X[ X_offset[ b ] + i + dec_subframe_offset ], 3 ); | ||
174 | sumSquared = silk_SMLABB( sumSquared, x_tmp, x_tmp ); | ||
175 | |||
176 | /* Safety check */ | ||
177 | silk_assert( sumSquared >= 0 ); | ||
178 | } | ||
179 | |||
180 | /* Add/saturate summed energy of current subframe */ | ||
181 | if( s < VAD_INTERNAL_SUBFRAMES - 1 ) { | ||
182 | Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], sumSquared ); | ||
183 | } else { | ||
184 | /* Look-ahead subframe */ | ||
185 | Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], silk_RSHIFT( sumSquared, 1 ) ); | ||
186 | } | ||
187 | |||
188 | dec_subframe_offset += dec_subframe_length; | ||
189 | } | ||
190 | psSilk_VAD->XnrgSubfr[ b ] = sumSquared; | ||
191 | } | ||
192 | |||
193 | /********************/ | ||
194 | /* Noise estimation */ | ||
195 | /********************/ | ||
196 | silk_VAD_GetNoiseLevels( &Xnrg[ 0 ], psSilk_VAD ); | ||
197 | |||
198 | /***********************************************/ | ||
199 | /* Signal-plus-noise to noise ratio estimation */ | ||
200 | /***********************************************/ | ||
201 | sumSquared = 0; | ||
202 | input_tilt = 0; | ||
203 | for( b = 0; b < VAD_N_BANDS; b++ ) { | ||
204 | speech_nrg = Xnrg[ b ] - psSilk_VAD->NL[ b ]; | ||
205 | if( speech_nrg > 0 ) { | ||
206 | /* Divide, with sufficient resolution */ | ||
207 | if( ( Xnrg[ b ] & 0xFF800000 ) == 0 ) { | ||
208 | NrgToNoiseRatio_Q8[ b ] = silk_DIV32( silk_LSHIFT( Xnrg[ b ], 8 ), psSilk_VAD->NL[ b ] + 1 ); | ||
209 | } else { | ||
210 | NrgToNoiseRatio_Q8[ b ] = silk_DIV32( Xnrg[ b ], silk_RSHIFT( psSilk_VAD->NL[ b ], 8 ) + 1 ); | ||
211 | } | ||
212 | |||
213 | /* Convert to log domain */ | ||
214 | SNR_Q7 = silk_lin2log( NrgToNoiseRatio_Q8[ b ] ) - 8 * 128; | ||
215 | |||
216 | /* Sum-of-squares */ | ||
217 | sumSquared = silk_SMLABB( sumSquared, SNR_Q7, SNR_Q7 ); /* Q14 */ | ||
218 | |||
219 | /* Tilt measure */ | ||
220 | if( speech_nrg < ( (opus_int32)1 << 20 ) ) { | ||
221 | /* Scale down SNR value for small subband speech energies */ | ||
222 | SNR_Q7 = silk_SMULWB( silk_LSHIFT( silk_SQRT_APPROX( speech_nrg ), 6 ), SNR_Q7 ); | ||
223 | } | ||
224 | input_tilt = silk_SMLAWB( input_tilt, tiltWeights[ b ], SNR_Q7 ); | ||
225 | } else { | ||
226 | NrgToNoiseRatio_Q8[ b ] = 256; | ||
227 | } | ||
228 | } | ||
229 | |||
230 | /* Mean-of-squares */ | ||
231 | sumSquared = silk_DIV32_16( sumSquared, VAD_N_BANDS ); /* Q14 */ | ||
232 | |||
233 | /* Root-mean-square approximation, scale to dBs, and write to output pointer */ | ||
234 | pSNR_dB_Q7 = (opus_int16)( 3 * silk_SQRT_APPROX( sumSquared ) ); /* Q7 */ | ||
235 | |||
236 | /*********************************/ | ||
237 | /* Speech Probability Estimation */ | ||
238 | /*********************************/ | ||
239 | SA_Q15 = silk_sigm_Q15( silk_SMULWB( VAD_SNR_FACTOR_Q16, pSNR_dB_Q7 ) - VAD_NEGATIVE_OFFSET_Q5 ); | ||
240 | |||
241 | /**************************/ | ||
242 | /* Frequency Tilt Measure */ | ||
243 | /**************************/ | ||
244 | psEncC->input_tilt_Q15 = silk_LSHIFT( silk_sigm_Q15( input_tilt ) - 16384, 1 ); | ||
245 | |||
246 | /**************************************************/ | ||
247 | /* Scale the sigmoid output based on power levels */ | ||
248 | /**************************************************/ | ||
249 | speech_nrg = 0; | ||
250 | for( b = 0; b < VAD_N_BANDS; b++ ) { | ||
251 | /* Accumulate signal-without-noise energies, higher frequency bands have more weight */ | ||
252 | speech_nrg += ( b + 1 ) * silk_RSHIFT( Xnrg[ b ] - psSilk_VAD->NL[ b ], 4 ); | ||
253 | } | ||
254 | |||
255 | if( psEncC->frame_length == 20 * psEncC->fs_kHz ) { | ||
256 | speech_nrg = silk_RSHIFT32( speech_nrg, 1 ); | ||
257 | } | ||
258 | /* Power scaling */ | ||
259 | if( speech_nrg <= 0 ) { | ||
260 | SA_Q15 = silk_RSHIFT( SA_Q15, 1 ); | ||
261 | } else if( speech_nrg < 16384 ) { | ||
262 | speech_nrg = silk_LSHIFT32( speech_nrg, 16 ); | ||
263 | |||
264 | /* square-root */ | ||
265 | speech_nrg = silk_SQRT_APPROX( speech_nrg ); | ||
266 | SA_Q15 = silk_SMULWB( 32768 + speech_nrg, SA_Q15 ); | ||
267 | } | ||
268 | |||
269 | /* Copy the resulting speech activity in Q8 */ | ||
270 | psEncC->speech_activity_Q8 = silk_min_int( silk_RSHIFT( SA_Q15, 7 ), silk_uint8_MAX ); | ||
271 | |||
272 | /***********************************/ | ||
273 | /* Energy Level and SNR estimation */ | ||
274 | /***********************************/ | ||
275 | /* Smoothing coefficient */ | ||
276 | smooth_coef_Q16 = silk_SMULWB( VAD_SNR_SMOOTH_COEF_Q18, silk_SMULWB( (opus_int32)SA_Q15, SA_Q15 ) ); | ||
277 | |||
278 | if( psEncC->frame_length == 10 * psEncC->fs_kHz ) { | ||
279 | smooth_coef_Q16 >>= 1; | ||
280 | } | ||
281 | |||
282 | for( b = 0; b < VAD_N_BANDS; b++ ) { | ||
283 | /* compute smoothed energy-to-noise ratio per band */ | ||
284 | psSilk_VAD->NrgRatioSmth_Q8[ b ] = silk_SMLAWB( psSilk_VAD->NrgRatioSmth_Q8[ b ], | ||
285 | NrgToNoiseRatio_Q8[ b ] - psSilk_VAD->NrgRatioSmth_Q8[ b ], smooth_coef_Q16 ); | ||
286 | |||
287 | /* signal to noise ratio in dB per band */ | ||
288 | SNR_Q7 = 3 * ( silk_lin2log( psSilk_VAD->NrgRatioSmth_Q8[b] ) - 8 * 128 ); | ||
289 | /* quality = sigmoid( 0.25 * ( SNR_dB - 16 ) ); */ | ||
290 | psEncC->input_quality_bands_Q15[ b ] = silk_sigm_Q15( silk_RSHIFT( SNR_Q7 - 16 * 128, 4 ) ); | ||
291 | } | ||
292 | |||
293 | RESTORE_STACK; | ||
294 | return( ret ); | ||
295 | } | ||
296 | |||
297 | /**************************/ | ||
298 | /* Noise level estimation */ | ||
299 | /**************************/ | ||
300 | # if !defined(OPUS_X86_MAY_HAVE_SSE4_1) | ||
301 | static OPUS_INLINE | ||
302 | #endif | ||
303 | void silk_VAD_GetNoiseLevels( | ||
304 | const opus_int32 pX[ VAD_N_BANDS ], /* I subband energies */ | ||
305 | silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */ | ||
306 | ) | ||
307 | { | ||
308 | opus_int k; | ||
309 | opus_int32 nl, nrg, inv_nrg; | ||
310 | opus_int coef, min_coef; | ||
311 | |||
312 | /* Initially faster smoothing */ | ||
313 | if( psSilk_VAD->counter < 1000 ) { /* 1000 = 20 sec */ | ||
314 | min_coef = silk_DIV32_16( silk_int16_MAX, silk_RSHIFT( psSilk_VAD->counter, 4 ) + 1 ); | ||
315 | /* Increment frame counter */ | ||
316 | psSilk_VAD->counter++; | ||
317 | } else { | ||
318 | min_coef = 0; | ||
319 | } | ||
320 | |||
321 | for( k = 0; k < VAD_N_BANDS; k++ ) { | ||
322 | /* Get old noise level estimate for current band */ | ||
323 | nl = psSilk_VAD->NL[ k ]; | ||
324 | silk_assert( nl >= 0 ); | ||
325 | |||
326 | /* Add bias */ | ||
327 | nrg = silk_ADD_POS_SAT32( pX[ k ], psSilk_VAD->NoiseLevelBias[ k ] ); | ||
328 | silk_assert( nrg > 0 ); | ||
329 | |||
330 | /* Invert energies */ | ||
331 | inv_nrg = silk_DIV32( silk_int32_MAX, nrg ); | ||
332 | silk_assert( inv_nrg >= 0 ); | ||
333 | |||
334 | /* Less update when subband energy is high */ | ||
335 | if( nrg > silk_LSHIFT( nl, 3 ) ) { | ||
336 | coef = VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 >> 3; | ||
337 | } else if( nrg < nl ) { | ||
338 | coef = VAD_NOISE_LEVEL_SMOOTH_COEF_Q16; | ||
339 | } else { | ||
340 | coef = silk_SMULWB( silk_SMULWW( inv_nrg, nl ), VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 << 1 ); | ||
341 | } | ||
342 | |||
343 | /* Initially faster smoothing */ | ||
344 | coef = silk_max_int( coef, min_coef ); | ||
345 | |||
346 | /* Smooth inverse energies */ | ||
347 | psSilk_VAD->inv_NL[ k ] = silk_SMLAWB( psSilk_VAD->inv_NL[ k ], inv_nrg - psSilk_VAD->inv_NL[ k ], coef ); | ||
348 | silk_assert( psSilk_VAD->inv_NL[ k ] >= 0 ); | ||
349 | |||
350 | /* Compute noise level by inverting again */ | ||
351 | nl = silk_DIV32( silk_int32_MAX, psSilk_VAD->inv_NL[ k ] ); | ||
352 | silk_assert( nl >= 0 ); | ||
353 | |||
354 | /* Limit noise levels (guarantee 7 bits of head room) */ | ||
355 | nl = silk_min( nl, 0x00FFFFFF ); | ||
356 | |||
357 | /* Store as part of state */ | ||
358 | psSilk_VAD->NL[ k ] = nl; | ||
359 | } | ||
360 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/VQ_WMat_EC.c b/lib/rbcodec/codecs/libopus/silk/VQ_WMat_EC.c new file mode 100644 index 0000000000..0f3d545c4e --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/VQ_WMat_EC.c | |||
@@ -0,0 +1,131 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main.h" | ||
33 | |||
34 | /* Entropy constrained matrix-weighted VQ, hard-coded to 5-element vectors, for a single input data vector */ | ||
35 | void silk_VQ_WMat_EC_c( | ||
36 | opus_int8 *ind, /* O index of best codebook vector */ | ||
37 | opus_int32 *res_nrg_Q15, /* O best residual energy */ | ||
38 | opus_int32 *rate_dist_Q8, /* O best total bitrate */ | ||
39 | opus_int *gain_Q7, /* O sum of absolute LTP coefficients */ | ||
40 | const opus_int32 *XX_Q17, /* I correlation matrix */ | ||
41 | const opus_int32 *xX_Q17, /* I correlation vector */ | ||
42 | const opus_int8 *cb_Q7, /* I codebook */ | ||
43 | const opus_uint8 *cb_gain_Q7, /* I codebook effective gain */ | ||
44 | const opus_uint8 *cl_Q5, /* I code length for each codebook vector */ | ||
45 | const opus_int subfr_len, /* I number of samples per subframe */ | ||
46 | const opus_int32 max_gain_Q7, /* I maximum sum of absolute LTP coefficients */ | ||
47 | const opus_int L /* I number of vectors in codebook */ | ||
48 | ) | ||
49 | { | ||
50 | opus_int k, gain_tmp_Q7; | ||
51 | const opus_int8 *cb_row_Q7; | ||
52 | opus_int32 neg_xX_Q24[ 5 ]; | ||
53 | opus_int32 sum1_Q15, sum2_Q24; | ||
54 | opus_int32 bits_res_Q8, bits_tot_Q8; | ||
55 | |||
56 | /* Negate and convert to new Q domain */ | ||
57 | neg_xX_Q24[ 0 ] = -silk_LSHIFT32( xX_Q17[ 0 ], 7 ); | ||
58 | neg_xX_Q24[ 1 ] = -silk_LSHIFT32( xX_Q17[ 1 ], 7 ); | ||
59 | neg_xX_Q24[ 2 ] = -silk_LSHIFT32( xX_Q17[ 2 ], 7 ); | ||
60 | neg_xX_Q24[ 3 ] = -silk_LSHIFT32( xX_Q17[ 3 ], 7 ); | ||
61 | neg_xX_Q24[ 4 ] = -silk_LSHIFT32( xX_Q17[ 4 ], 7 ); | ||
62 | |||
63 | /* Loop over codebook */ | ||
64 | *rate_dist_Q8 = silk_int32_MAX; | ||
65 | *res_nrg_Q15 = silk_int32_MAX; | ||
66 | cb_row_Q7 = cb_Q7; | ||
67 | /* In things go really bad, at least *ind is set to something safe. */ | ||
68 | *ind = 0; | ||
69 | for( k = 0; k < L; k++ ) { | ||
70 | opus_int32 penalty; | ||
71 | gain_tmp_Q7 = cb_gain_Q7[k]; | ||
72 | /* Weighted rate */ | ||
73 | /* Quantization error: 1 - 2 * xX * cb + cb' * XX * cb */ | ||
74 | sum1_Q15 = SILK_FIX_CONST( 1.001, 15 ); | ||
75 | |||
76 | /* Penalty for too large gain */ | ||
77 | penalty = silk_LSHIFT32( silk_max( silk_SUB32( gain_tmp_Q7, max_gain_Q7 ), 0 ), 11 ); | ||
78 | |||
79 | /* first row of XX_Q17 */ | ||
80 | sum2_Q24 = silk_MLA( neg_xX_Q24[ 0 ], XX_Q17[ 1 ], cb_row_Q7[ 1 ] ); | ||
81 | sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 2 ], cb_row_Q7[ 2 ] ); | ||
82 | sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 3 ], cb_row_Q7[ 3 ] ); | ||
83 | sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 4 ], cb_row_Q7[ 4 ] ); | ||
84 | sum2_Q24 = silk_LSHIFT32( sum2_Q24, 1 ); | ||
85 | sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 0 ], cb_row_Q7[ 0 ] ); | ||
86 | sum1_Q15 = silk_SMLAWB( sum1_Q15, sum2_Q24, cb_row_Q7[ 0 ] ); | ||
87 | |||
88 | /* second row of XX_Q17 */ | ||
89 | sum2_Q24 = silk_MLA( neg_xX_Q24[ 1 ], XX_Q17[ 7 ], cb_row_Q7[ 2 ] ); | ||
90 | sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 8 ], cb_row_Q7[ 3 ] ); | ||
91 | sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 9 ], cb_row_Q7[ 4 ] ); | ||
92 | sum2_Q24 = silk_LSHIFT32( sum2_Q24, 1 ); | ||
93 | sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 6 ], cb_row_Q7[ 1 ] ); | ||
94 | sum1_Q15 = silk_SMLAWB( sum1_Q15, sum2_Q24, cb_row_Q7[ 1 ] ); | ||
95 | |||
96 | /* third row of XX_Q17 */ | ||
97 | sum2_Q24 = silk_MLA( neg_xX_Q24[ 2 ], XX_Q17[ 13 ], cb_row_Q7[ 3 ] ); | ||
98 | sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 14 ], cb_row_Q7[ 4 ] ); | ||
99 | sum2_Q24 = silk_LSHIFT32( sum2_Q24, 1 ); | ||
100 | sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 12 ], cb_row_Q7[ 2 ] ); | ||
101 | sum1_Q15 = silk_SMLAWB( sum1_Q15, sum2_Q24, cb_row_Q7[ 2 ] ); | ||
102 | |||
103 | /* fourth row of XX_Q17 */ | ||
104 | sum2_Q24 = silk_MLA( neg_xX_Q24[ 3 ], XX_Q17[ 19 ], cb_row_Q7[ 4 ] ); | ||
105 | sum2_Q24 = silk_LSHIFT32( sum2_Q24, 1 ); | ||
106 | sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 18 ], cb_row_Q7[ 3 ] ); | ||
107 | sum1_Q15 = silk_SMLAWB( sum1_Q15, sum2_Q24, cb_row_Q7[ 3 ] ); | ||
108 | |||
109 | /* last row of XX_Q17 */ | ||
110 | sum2_Q24 = silk_LSHIFT32( neg_xX_Q24[ 4 ], 1 ); | ||
111 | sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 24 ], cb_row_Q7[ 4 ] ); | ||
112 | sum1_Q15 = silk_SMLAWB( sum1_Q15, sum2_Q24, cb_row_Q7[ 4 ] ); | ||
113 | |||
114 | /* find best */ | ||
115 | if( sum1_Q15 >= 0 ) { | ||
116 | /* Translate residual energy to bits using high-rate assumption (6 dB ==> 1 bit/sample) */ | ||
117 | bits_res_Q8 = silk_SMULBB( subfr_len, silk_lin2log( sum1_Q15 + penalty) - (15 << 7) ); | ||
118 | /* In the following line we reduce the codelength component by half ("-1"); seems to slghtly improve quality */ | ||
119 | bits_tot_Q8 = silk_ADD_LSHIFT32( bits_res_Q8, cl_Q5[ k ], 3-1 ); | ||
120 | if( bits_tot_Q8 <= *rate_dist_Q8 ) { | ||
121 | *rate_dist_Q8 = bits_tot_Q8; | ||
122 | *res_nrg_Q15 = sum1_Q15 + penalty; | ||
123 | *ind = (opus_int8)k; | ||
124 | *gain_Q7 = gain_tmp_Q7; | ||
125 | } | ||
126 | } | ||
127 | |||
128 | /* Go to next cbk vector */ | ||
129 | cb_row_Q7 += LTP_ORDER; | ||
130 | } | ||
131 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/ana_filt_bank_1.c b/lib/rbcodec/codecs/libopus/silk/ana_filt_bank_1.c new file mode 100644 index 0000000000..24cfb03fdb --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/ana_filt_bank_1.c | |||
@@ -0,0 +1,74 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "SigProc_FIX.h" | ||
33 | |||
34 | /* Coefficients for 2-band filter bank based on first-order allpass filters */ | ||
35 | static opus_int16 A_fb1_20 = 5394 << 1; | ||
36 | static opus_int16 A_fb1_21 = -24290; /* (opus_int16)(20623 << 1) */ | ||
37 | |||
38 | /* Split signal into two decimated bands using first-order allpass filters */ | ||
39 | void silk_ana_filt_bank_1( | ||
40 | const opus_int16 *in, /* I Input signal [N] */ | ||
41 | opus_int32 *S, /* I/O State vector [2] */ | ||
42 | opus_int16 *outL, /* O Low band [N/2] */ | ||
43 | opus_int16 *outH, /* O High band [N/2] */ | ||
44 | const opus_int32 N /* I Number of input samples */ | ||
45 | ) | ||
46 | { | ||
47 | opus_int k, N2 = silk_RSHIFT( N, 1 ); | ||
48 | opus_int32 in32, X, Y, out_1, out_2; | ||
49 | |||
50 | /* Internal variables and state are in Q10 format */ | ||
51 | for( k = 0; k < N2; k++ ) { | ||
52 | /* Convert to Q10 */ | ||
53 | in32 = silk_LSHIFT( (opus_int32)in[ 2 * k ], 10 ); | ||
54 | |||
55 | /* All-pass section for even input sample */ | ||
56 | Y = silk_SUB32( in32, S[ 0 ] ); | ||
57 | X = silk_SMLAWB( Y, Y, A_fb1_21 ); | ||
58 | out_1 = silk_ADD32( S[ 0 ], X ); | ||
59 | S[ 0 ] = silk_ADD32( in32, X ); | ||
60 | |||
61 | /* Convert to Q10 */ | ||
62 | in32 = silk_LSHIFT( (opus_int32)in[ 2 * k + 1 ], 10 ); | ||
63 | |||
64 | /* All-pass section for odd input sample, and add to output of previous section */ | ||
65 | Y = silk_SUB32( in32, S[ 1 ] ); | ||
66 | X = silk_SMULWB( Y, A_fb1_20 ); | ||
67 | out_2 = silk_ADD32( S[ 1 ], X ); | ||
68 | S[ 1 ] = silk_ADD32( in32, X ); | ||
69 | |||
70 | /* Add/subtract, convert back to int16 and store to output */ | ||
71 | outL[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_ADD32( out_2, out_1 ), 11 ) ); | ||
72 | outH[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SUB32( out_2, out_1 ), 11 ) ); | ||
73 | } | ||
74 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/arm/LPC_inv_pred_gain_arm.h b/lib/rbcodec/codecs/libopus/silk/arm/LPC_inv_pred_gain_arm.h new file mode 100644 index 0000000000..9895b555c8 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/arm/LPC_inv_pred_gain_arm.h | |||
@@ -0,0 +1,57 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2017 Google Inc. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifndef SILK_LPC_INV_PRED_GAIN_ARM_H | ||
29 | # define SILK_LPC_INV_PRED_GAIN_ARM_H | ||
30 | |||
31 | # include "celt/arm/armcpu.h" | ||
32 | |||
33 | # if defined(OPUS_ARM_MAY_HAVE_NEON_INTR) | ||
34 | opus_int32 silk_LPC_inverse_pred_gain_neon( /* O Returns inverse prediction gain in energy domain, Q30 */ | ||
35 | const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */ | ||
36 | const opus_int order /* I Prediction order */ | ||
37 | ); | ||
38 | |||
39 | # if !defined(OPUS_HAVE_RTCD) && defined(OPUS_ARM_PRESUME_NEON) | ||
40 | # define OVERRIDE_silk_LPC_inverse_pred_gain (1) | ||
41 | # define silk_LPC_inverse_pred_gain(A_Q12, order, arch) ((void)(arch), PRESUME_NEON(silk_LPC_inverse_pred_gain)(A_Q12, order)) | ||
42 | # endif | ||
43 | # endif | ||
44 | |||
45 | # if !defined(OVERRIDE_silk_LPC_inverse_pred_gain) | ||
46 | /*Is run-time CPU detection enabled on this platform?*/ | ||
47 | # if defined(OPUS_HAVE_RTCD) && (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR)) | ||
48 | extern opus_int32 (*const SILK_LPC_INVERSE_PRED_GAIN_IMPL[OPUS_ARCHMASK+1])(const opus_int16 *A_Q12, const opus_int order); | ||
49 | # define OVERRIDE_silk_LPC_inverse_pred_gain (1) | ||
50 | # define silk_LPC_inverse_pred_gain(A_Q12, order, arch) ((*SILK_LPC_INVERSE_PRED_GAIN_IMPL[(arch)&OPUS_ARCHMASK])(A_Q12, order)) | ||
51 | # elif defined(OPUS_ARM_PRESUME_NEON_INTR) | ||
52 | # define OVERRIDE_silk_LPC_inverse_pred_gain (1) | ||
53 | # define silk_LPC_inverse_pred_gain(A_Q12, order, arch) ((void)(arch), silk_LPC_inverse_pred_gain_neon(A_Q12, order)) | ||
54 | # endif | ||
55 | # endif | ||
56 | |||
57 | #endif /* end SILK_LPC_INV_PRED_GAIN_ARM_H */ | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/arm/LPC_inv_pred_gain_neon_intr.c b/lib/rbcodec/codecs/libopus/silk/arm/LPC_inv_pred_gain_neon_intr.c new file mode 100644 index 0000000000..ab426bcd66 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/arm/LPC_inv_pred_gain_neon_intr.c | |||
@@ -0,0 +1,280 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2017 Google Inc. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include <arm_neon.h> | ||
33 | #include "SigProc_FIX.h" | ||
34 | #include "define.h" | ||
35 | |||
36 | #define QA 24 | ||
37 | #define A_LIMIT SILK_FIX_CONST( 0.99975, QA ) | ||
38 | |||
39 | #define MUL32_FRAC_Q(a32, b32, Q) ((opus_int32)(silk_RSHIFT_ROUND64(silk_SMULL(a32, b32), Q))) | ||
40 | |||
41 | /* The difficulty is how to judge a 64-bit signed integer tmp64 is 32-bit overflowed, | ||
42 | * since NEON has no 64-bit min, max or comparison instructions. | ||
43 | * A failed idea is to compare the results of vmovn(tmp64) and vqmovn(tmp64) whether they are equal or not. | ||
44 | * However, this idea fails when the tmp64 is something like 0xFFFFFFF980000000. | ||
45 | * Here we know that mult2Q >= 1, so the highest bit (bit 63, sign bit) of tmp64 must equal to bit 62. | ||
46 | * tmp64 was shifted left by 1 and we got tmp64'. If high_half(tmp64') != 0 and high_half(tmp64') != -1, | ||
47 | * then we know that bit 31 to bit 63 of tmp64 can not all be the sign bit, and therefore tmp64 is 32-bit overflowed. | ||
48 | * That is, we judge if tmp64' > 0x00000000FFFFFFFF, or tmp64' <= 0xFFFFFFFF00000000. | ||
49 | * We use narrowing shift right 31 bits to tmp32' to save data bandwidth and instructions. | ||
50 | * That is, we judge if tmp32' > 0x00000000, or tmp32' <= 0xFFFFFFFF. | ||
51 | */ | ||
52 | |||
53 | /* Compute inverse of LPC prediction gain, and */ | ||
54 | /* test if LPC coefficients are stable (all poles within unit circle) */ | ||
55 | static OPUS_INLINE opus_int32 LPC_inverse_pred_gain_QA_neon( /* O Returns inverse prediction gain in energy domain, Q30 */ | ||
56 | opus_int32 A_QA[ SILK_MAX_ORDER_LPC ], /* I Prediction coefficients */ | ||
57 | const opus_int order /* I Prediction order */ | ||
58 | ) | ||
59 | { | ||
60 | opus_int k, n, mult2Q; | ||
61 | opus_int32 invGain_Q30, rc_Q31, rc_mult1_Q30, rc_mult2, tmp1, tmp2; | ||
62 | opus_int32 max, min; | ||
63 | int32x4_t max_s32x4, min_s32x4; | ||
64 | int32x2_t max_s32x2, min_s32x2; | ||
65 | |||
66 | max_s32x4 = vdupq_n_s32( silk_int32_MIN ); | ||
67 | min_s32x4 = vdupq_n_s32( silk_int32_MAX ); | ||
68 | invGain_Q30 = SILK_FIX_CONST( 1, 30 ); | ||
69 | for( k = order - 1; k > 0; k-- ) { | ||
70 | int32x2_t rc_Q31_s32x2, rc_mult2_s32x2; | ||
71 | int64x2_t mult2Q_s64x2; | ||
72 | |||
73 | /* Check for stability */ | ||
74 | if( ( A_QA[ k ] > A_LIMIT ) || ( A_QA[ k ] < -A_LIMIT ) ) { | ||
75 | return 0; | ||
76 | } | ||
77 | |||
78 | /* Set RC equal to negated AR coef */ | ||
79 | rc_Q31 = -silk_LSHIFT( A_QA[ k ], 31 - QA ); | ||
80 | |||
81 | /* rc_mult1_Q30 range: [ 1 : 2^30 ] */ | ||
82 | rc_mult1_Q30 = silk_SUB32( SILK_FIX_CONST( 1, 30 ), silk_SMMUL( rc_Q31, rc_Q31 ) ); | ||
83 | silk_assert( rc_mult1_Q30 > ( 1 << 15 ) ); /* reduce A_LIMIT if fails */ | ||
84 | silk_assert( rc_mult1_Q30 <= ( 1 << 30 ) ); | ||
85 | |||
86 | /* Update inverse gain */ | ||
87 | /* invGain_Q30 range: [ 0 : 2^30 ] */ | ||
88 | invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 ); | ||
89 | silk_assert( invGain_Q30 >= 0 ); | ||
90 | silk_assert( invGain_Q30 <= ( 1 << 30 ) ); | ||
91 | if( invGain_Q30 < SILK_FIX_CONST( 1.0f / MAX_PREDICTION_POWER_GAIN, 30 ) ) { | ||
92 | return 0; | ||
93 | } | ||
94 | |||
95 | /* rc_mult2 range: [ 2^30 : silk_int32_MAX ] */ | ||
96 | mult2Q = 32 - silk_CLZ32( silk_abs( rc_mult1_Q30 ) ); | ||
97 | rc_mult2 = silk_INVERSE32_varQ( rc_mult1_Q30, mult2Q + 30 ); | ||
98 | |||
99 | /* Update AR coefficient */ | ||
100 | rc_Q31_s32x2 = vdup_n_s32( rc_Q31 ); | ||
101 | mult2Q_s64x2 = vdupq_n_s64( -mult2Q ); | ||
102 | rc_mult2_s32x2 = vdup_n_s32( rc_mult2 ); | ||
103 | |||
104 | for( n = 0; n < ( ( k + 1 ) >> 1 ) - 3; n += 4 ) { | ||
105 | /* We always calculate extra elements of A_QA buffer when ( k % 4 ) != 0, to take the advantage of SIMD parallelization. */ | ||
106 | int32x4_t tmp1_s32x4, tmp2_s32x4, t0_s32x4, t1_s32x4, s0_s32x4, s1_s32x4, t_QA0_s32x4, t_QA1_s32x4; | ||
107 | int64x2_t t0_s64x2, t1_s64x2, t2_s64x2, t3_s64x2; | ||
108 | tmp1_s32x4 = vld1q_s32( A_QA + n ); | ||
109 | tmp2_s32x4 = vld1q_s32( A_QA + k - n - 4 ); | ||
110 | tmp2_s32x4 = vrev64q_s32( tmp2_s32x4 ); | ||
111 | tmp2_s32x4 = vcombine_s32( vget_high_s32( tmp2_s32x4 ), vget_low_s32( tmp2_s32x4 ) ); | ||
112 | t0_s32x4 = vqrdmulhq_lane_s32( tmp2_s32x4, rc_Q31_s32x2, 0 ); | ||
113 | t1_s32x4 = vqrdmulhq_lane_s32( tmp1_s32x4, rc_Q31_s32x2, 0 ); | ||
114 | t_QA0_s32x4 = vqsubq_s32( tmp1_s32x4, t0_s32x4 ); | ||
115 | t_QA1_s32x4 = vqsubq_s32( tmp2_s32x4, t1_s32x4 ); | ||
116 | t0_s64x2 = vmull_s32( vget_low_s32 ( t_QA0_s32x4 ), rc_mult2_s32x2 ); | ||
117 | t1_s64x2 = vmull_s32( vget_high_s32( t_QA0_s32x4 ), rc_mult2_s32x2 ); | ||
118 | t2_s64x2 = vmull_s32( vget_low_s32 ( t_QA1_s32x4 ), rc_mult2_s32x2 ); | ||
119 | t3_s64x2 = vmull_s32( vget_high_s32( t_QA1_s32x4 ), rc_mult2_s32x2 ); | ||
120 | t0_s64x2 = vrshlq_s64( t0_s64x2, mult2Q_s64x2 ); | ||
121 | t1_s64x2 = vrshlq_s64( t1_s64x2, mult2Q_s64x2 ); | ||
122 | t2_s64x2 = vrshlq_s64( t2_s64x2, mult2Q_s64x2 ); | ||
123 | t3_s64x2 = vrshlq_s64( t3_s64x2, mult2Q_s64x2 ); | ||
124 | t0_s32x4 = vcombine_s32( vmovn_s64( t0_s64x2 ), vmovn_s64( t1_s64x2 ) ); | ||
125 | t1_s32x4 = vcombine_s32( vmovn_s64( t2_s64x2 ), vmovn_s64( t3_s64x2 ) ); | ||
126 | s0_s32x4 = vcombine_s32( vshrn_n_s64( t0_s64x2, 31 ), vshrn_n_s64( t1_s64x2, 31 ) ); | ||
127 | s1_s32x4 = vcombine_s32( vshrn_n_s64( t2_s64x2, 31 ), vshrn_n_s64( t3_s64x2, 31 ) ); | ||
128 | max_s32x4 = vmaxq_s32( max_s32x4, s0_s32x4 ); | ||
129 | min_s32x4 = vminq_s32( min_s32x4, s0_s32x4 ); | ||
130 | max_s32x4 = vmaxq_s32( max_s32x4, s1_s32x4 ); | ||
131 | min_s32x4 = vminq_s32( min_s32x4, s1_s32x4 ); | ||
132 | t1_s32x4 = vrev64q_s32( t1_s32x4 ); | ||
133 | t1_s32x4 = vcombine_s32( vget_high_s32( t1_s32x4 ), vget_low_s32( t1_s32x4 ) ); | ||
134 | vst1q_s32( A_QA + n, t0_s32x4 ); | ||
135 | vst1q_s32( A_QA + k - n - 4, t1_s32x4 ); | ||
136 | } | ||
137 | for( ; n < (k + 1) >> 1; n++ ) { | ||
138 | opus_int64 tmp64; | ||
139 | tmp1 = A_QA[ n ]; | ||
140 | tmp2 = A_QA[ k - n - 1 ]; | ||
141 | tmp64 = silk_RSHIFT_ROUND64( silk_SMULL( silk_SUB_SAT32(tmp1, | ||
142 | MUL32_FRAC_Q( tmp2, rc_Q31, 31 ) ), rc_mult2 ), mult2Q); | ||
143 | if( tmp64 > silk_int32_MAX || tmp64 < silk_int32_MIN ) { | ||
144 | return 0; | ||
145 | } | ||
146 | A_QA[ n ] = ( opus_int32 )tmp64; | ||
147 | tmp64 = silk_RSHIFT_ROUND64( silk_SMULL( silk_SUB_SAT32(tmp2, | ||
148 | MUL32_FRAC_Q( tmp1, rc_Q31, 31 ) ), rc_mult2), mult2Q); | ||
149 | if( tmp64 > silk_int32_MAX || tmp64 < silk_int32_MIN ) { | ||
150 | return 0; | ||
151 | } | ||
152 | A_QA[ k - n - 1 ] = ( opus_int32 )tmp64; | ||
153 | } | ||
154 | } | ||
155 | |||
156 | /* Check for stability */ | ||
157 | if( ( A_QA[ k ] > A_LIMIT ) || ( A_QA[ k ] < -A_LIMIT ) ) { | ||
158 | return 0; | ||
159 | } | ||
160 | |||
161 | max_s32x2 = vmax_s32( vget_low_s32( max_s32x4 ), vget_high_s32( max_s32x4 ) ); | ||
162 | min_s32x2 = vmin_s32( vget_low_s32( min_s32x4 ), vget_high_s32( min_s32x4 ) ); | ||
163 | max_s32x2 = vmax_s32( max_s32x2, vreinterpret_s32_s64( vshr_n_s64( vreinterpret_s64_s32( max_s32x2 ), 32 ) ) ); | ||
164 | min_s32x2 = vmin_s32( min_s32x2, vreinterpret_s32_s64( vshr_n_s64( vreinterpret_s64_s32( min_s32x2 ), 32 ) ) ); | ||
165 | max = vget_lane_s32( max_s32x2, 0 ); | ||
166 | min = vget_lane_s32( min_s32x2, 0 ); | ||
167 | if( ( max > 0 ) || ( min < -1 ) ) { | ||
168 | return 0; | ||
169 | } | ||
170 | |||
171 | /* Set RC equal to negated AR coef */ | ||
172 | rc_Q31 = -silk_LSHIFT( A_QA[ 0 ], 31 - QA ); | ||
173 | |||
174 | /* Range: [ 1 : 2^30 ] */ | ||
175 | rc_mult1_Q30 = silk_SUB32( SILK_FIX_CONST( 1, 30 ), silk_SMMUL( rc_Q31, rc_Q31 ) ); | ||
176 | |||
177 | /* Update inverse gain */ | ||
178 | /* Range: [ 0 : 2^30 ] */ | ||
179 | invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 ); | ||
180 | silk_assert( invGain_Q30 >= 0 ); | ||
181 | silk_assert( invGain_Q30 <= ( 1 << 30 ) ); | ||
182 | if( invGain_Q30 < SILK_FIX_CONST( 1.0f / MAX_PREDICTION_POWER_GAIN, 30 ) ) { | ||
183 | return 0; | ||
184 | } | ||
185 | |||
186 | return invGain_Q30; | ||
187 | } | ||
188 | |||
189 | /* For input in Q12 domain */ | ||
190 | opus_int32 silk_LPC_inverse_pred_gain_neon( /* O Returns inverse prediction gain in energy domain, Q30 */ | ||
191 | const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */ | ||
192 | const opus_int order /* I Prediction order */ | ||
193 | ) | ||
194 | { | ||
195 | #ifdef OPUS_CHECK_ASM | ||
196 | const opus_int32 invGain_Q30_c = silk_LPC_inverse_pred_gain_c( A_Q12, order ); | ||
197 | #endif | ||
198 | |||
199 | opus_int32 invGain_Q30; | ||
200 | if( ( SILK_MAX_ORDER_LPC != 24 ) || ( order & 1 )) { | ||
201 | invGain_Q30 = silk_LPC_inverse_pred_gain_c( A_Q12, order ); | ||
202 | } | ||
203 | else { | ||
204 | opus_int32 Atmp_QA[ SILK_MAX_ORDER_LPC ]; | ||
205 | opus_int32 DC_resp; | ||
206 | int16x8_t t0_s16x8, t1_s16x8, t2_s16x8; | ||
207 | int32x4_t t0_s32x4; | ||
208 | const opus_int leftover = order & 7; | ||
209 | |||
210 | /* Increase Q domain of the AR coefficients */ | ||
211 | t0_s16x8 = vld1q_s16( A_Q12 + 0 ); | ||
212 | t1_s16x8 = vld1q_s16( A_Q12 + 8 ); | ||
213 | t2_s16x8 = vld1q_s16( A_Q12 + 16 ); | ||
214 | t0_s32x4 = vpaddlq_s16( t0_s16x8 ); | ||
215 | |||
216 | switch( order - leftover ) | ||
217 | { | ||
218 | case 24: | ||
219 | t0_s32x4 = vpadalq_s16( t0_s32x4, t2_s16x8 ); | ||
220 | /* FALLTHROUGH */ | ||
221 | |||
222 | case 16: | ||
223 | t0_s32x4 = vpadalq_s16( t0_s32x4, t1_s16x8 ); | ||
224 | vst1q_s32( Atmp_QA + 16, vshll_n_s16( vget_low_s16 ( t2_s16x8 ), QA - 12 ) ); | ||
225 | vst1q_s32( Atmp_QA + 20, vshll_n_s16( vget_high_s16( t2_s16x8 ), QA - 12 ) ); | ||
226 | /* FALLTHROUGH */ | ||
227 | |||
228 | case 8: | ||
229 | { | ||
230 | const int32x2_t t_s32x2 = vpadd_s32( vget_low_s32( t0_s32x4 ), vget_high_s32( t0_s32x4 ) ); | ||
231 | const int64x1_t t_s64x1 = vpaddl_s32( t_s32x2 ); | ||
232 | DC_resp = vget_lane_s32( vreinterpret_s32_s64( t_s64x1 ), 0 ); | ||
233 | vst1q_s32( Atmp_QA + 8, vshll_n_s16( vget_low_s16 ( t1_s16x8 ), QA - 12 ) ); | ||
234 | vst1q_s32( Atmp_QA + 12, vshll_n_s16( vget_high_s16( t1_s16x8 ), QA - 12 ) ); | ||
235 | } | ||
236 | break; | ||
237 | |||
238 | default: | ||
239 | DC_resp = 0; | ||
240 | break; | ||
241 | } | ||
242 | A_Q12 += order - leftover; | ||
243 | |||
244 | switch( leftover ) | ||
245 | { | ||
246 | case 6: | ||
247 | DC_resp += (opus_int32)A_Q12[ 5 ]; | ||
248 | DC_resp += (opus_int32)A_Q12[ 4 ]; | ||
249 | /* FALLTHROUGH */ | ||
250 | |||
251 | case 4: | ||
252 | DC_resp += (opus_int32)A_Q12[ 3 ]; | ||
253 | DC_resp += (opus_int32)A_Q12[ 2 ]; | ||
254 | /* FALLTHROUGH */ | ||
255 | |||
256 | case 2: | ||
257 | DC_resp += (opus_int32)A_Q12[ 1 ]; | ||
258 | DC_resp += (opus_int32)A_Q12[ 0 ]; | ||
259 | /* FALLTHROUGH */ | ||
260 | |||
261 | default: | ||
262 | break; | ||
263 | } | ||
264 | |||
265 | /* If the DC is unstable, we don't even need to do the full calculations */ | ||
266 | if( DC_resp >= 4096 ) { | ||
267 | invGain_Q30 = 0; | ||
268 | } else { | ||
269 | vst1q_s32( Atmp_QA + 0, vshll_n_s16( vget_low_s16 ( t0_s16x8 ), QA - 12 ) ); | ||
270 | vst1q_s32( Atmp_QA + 4, vshll_n_s16( vget_high_s16( t0_s16x8 ), QA - 12 ) ); | ||
271 | invGain_Q30 = LPC_inverse_pred_gain_QA_neon( Atmp_QA, order ); | ||
272 | } | ||
273 | } | ||
274 | |||
275 | #ifdef OPUS_CHECK_ASM | ||
276 | silk_assert( invGain_Q30_c == invGain_Q30 ); | ||
277 | #endif | ||
278 | |||
279 | return invGain_Q30; | ||
280 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/arm/NSQ_del_dec_arm.h b/lib/rbcodec/codecs/libopus/silk/arm/NSQ_del_dec_arm.h new file mode 100644 index 0000000000..9e76e16927 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/arm/NSQ_del_dec_arm.h | |||
@@ -0,0 +1,100 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2017 Google Inc. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifndef SILK_NSQ_DEL_DEC_ARM_H | ||
29 | #define SILK_NSQ_DEL_DEC_ARM_H | ||
30 | |||
31 | #include "celt/arm/armcpu.h" | ||
32 | |||
33 | #if defined(OPUS_ARM_MAY_HAVE_NEON_INTR) | ||
34 | void silk_NSQ_del_dec_neon( | ||
35 | const silk_encoder_state *psEncC, silk_nsq_state *NSQ, | ||
36 | SideInfoIndices *psIndices, const opus_int16 x16[], opus_int8 pulses[], | ||
37 | const opus_int16 PredCoef_Q12[2 * MAX_LPC_ORDER], | ||
38 | const opus_int16 LTPCoef_Q14[LTP_ORDER * MAX_NB_SUBFR], | ||
39 | const opus_int16 AR_Q13[MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER], | ||
40 | const opus_int HarmShapeGain_Q14[MAX_NB_SUBFR], | ||
41 | const opus_int Tilt_Q14[MAX_NB_SUBFR], | ||
42 | const opus_int32 LF_shp_Q14[MAX_NB_SUBFR], | ||
43 | const opus_int32 Gains_Q16[MAX_NB_SUBFR], | ||
44 | const opus_int pitchL[MAX_NB_SUBFR], const opus_int Lambda_Q10, | ||
45 | const opus_int LTP_scale_Q14); | ||
46 | |||
47 | #if !defined(OPUS_HAVE_RTCD) | ||
48 | #define OVERRIDE_silk_NSQ_del_dec (1) | ||
49 | #define silk_NSQ_del_dec(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, \ | ||
50 | LTPCoef_Q14, AR_Q13, HarmShapeGain_Q14, Tilt_Q14, \ | ||
51 | LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, \ | ||
52 | LTP_scale_Q14, arch) \ | ||
53 | ((void)(arch), \ | ||
54 | PRESUME_NEON(silk_NSQ_del_dec)( \ | ||
55 | psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, \ | ||
56 | AR_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, \ | ||
57 | Lambda_Q10, LTP_scale_Q14)) | ||
58 | #endif | ||
59 | #endif | ||
60 | |||
61 | #if !defined(OVERRIDE_silk_NSQ_del_dec) | ||
62 | /*Is run-time CPU detection enabled on this platform?*/ | ||
63 | #if defined(OPUS_HAVE_RTCD) && (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && \ | ||
64 | !defined(OPUS_ARM_PRESUME_NEON_INTR)) | ||
65 | extern void (*const SILK_NSQ_DEL_DEC_IMPL[OPUS_ARCHMASK + 1])( | ||
66 | const silk_encoder_state *psEncC, silk_nsq_state *NSQ, | ||
67 | SideInfoIndices *psIndices, const opus_int16 x16[], opus_int8 pulses[], | ||
68 | const opus_int16 PredCoef_Q12[2 * MAX_LPC_ORDER], | ||
69 | const opus_int16 LTPCoef_Q14[LTP_ORDER * MAX_NB_SUBFR], | ||
70 | const opus_int16 AR_Q13[MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER], | ||
71 | const opus_int HarmShapeGain_Q14[MAX_NB_SUBFR], | ||
72 | const opus_int Tilt_Q14[MAX_NB_SUBFR], | ||
73 | const opus_int32 LF_shp_Q14[MAX_NB_SUBFR], | ||
74 | const opus_int32 Gains_Q16[MAX_NB_SUBFR], | ||
75 | const opus_int pitchL[MAX_NB_SUBFR], const opus_int Lambda_Q10, | ||
76 | const opus_int LTP_scale_Q14); | ||
77 | #define OVERRIDE_silk_NSQ_del_dec (1) | ||
78 | #define silk_NSQ_del_dec(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, \ | ||
79 | LTPCoef_Q14, AR_Q13, HarmShapeGain_Q14, Tilt_Q14, \ | ||
80 | LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, \ | ||
81 | LTP_scale_Q14, arch) \ | ||
82 | ((*SILK_NSQ_DEL_DEC_IMPL[(arch)&OPUS_ARCHMASK])( \ | ||
83 | psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, \ | ||
84 | AR_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, \ | ||
85 | Lambda_Q10, LTP_scale_Q14)) | ||
86 | #elif defined(OPUS_ARM_PRESUME_NEON_INTR) | ||
87 | #define OVERRIDE_silk_NSQ_del_dec (1) | ||
88 | #define silk_NSQ_del_dec(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, \ | ||
89 | LTPCoef_Q14, AR_Q13, HarmShapeGain_Q14, Tilt_Q14, \ | ||
90 | LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, \ | ||
91 | LTP_scale_Q14, arch) \ | ||
92 | ((void)(arch), \ | ||
93 | silk_NSQ_del_dec_neon(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, \ | ||
94 | LTPCoef_Q14, AR_Q13, HarmShapeGain_Q14, Tilt_Q14, \ | ||
95 | LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, \ | ||
96 | LTP_scale_Q14)) | ||
97 | #endif | ||
98 | #endif | ||
99 | |||
100 | #endif /* end SILK_NSQ_DEL_DEC_ARM_H */ | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/arm/NSQ_del_dec_neon_intr.c b/lib/rbcodec/codecs/libopus/silk/arm/NSQ_del_dec_neon_intr.c new file mode 100644 index 0000000000..212410f362 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/arm/NSQ_del_dec_neon_intr.c | |||
@@ -0,0 +1,1124 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2017 Google Inc. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include <arm_neon.h> | ||
33 | #ifdef OPUS_CHECK_ASM | ||
34 | # include <string.h> | ||
35 | #endif | ||
36 | #include "main.h" | ||
37 | #include "stack_alloc.h" | ||
38 | |||
39 | /* NEON intrinsics optimization now can only parallelize up to 4 delay decision states. */ | ||
40 | /* If there are more states, C function is called, and this optimization must be expanded. */ | ||
41 | #define NEON_MAX_DEL_DEC_STATES 4 | ||
42 | |||
43 | typedef struct { | ||
44 | opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH ][ NEON_MAX_DEL_DEC_STATES ]; | ||
45 | opus_int32 RandState[ DECISION_DELAY ][ NEON_MAX_DEL_DEC_STATES ]; | ||
46 | opus_int32 Q_Q10[ DECISION_DELAY ][ NEON_MAX_DEL_DEC_STATES ]; | ||
47 | opus_int32 Xq_Q14[ DECISION_DELAY ][ NEON_MAX_DEL_DEC_STATES ]; | ||
48 | opus_int32 Pred_Q15[ DECISION_DELAY ][ NEON_MAX_DEL_DEC_STATES ]; | ||
49 | opus_int32 Shape_Q14[ DECISION_DELAY ][ NEON_MAX_DEL_DEC_STATES ]; | ||
50 | opus_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ][ NEON_MAX_DEL_DEC_STATES ]; | ||
51 | opus_int32 LF_AR_Q14[ NEON_MAX_DEL_DEC_STATES ]; | ||
52 | opus_int32 Diff_Q14[ NEON_MAX_DEL_DEC_STATES ]; | ||
53 | opus_int32 Seed[ NEON_MAX_DEL_DEC_STATES ]; | ||
54 | opus_int32 SeedInit[ NEON_MAX_DEL_DEC_STATES ]; | ||
55 | opus_int32 RD_Q10[ NEON_MAX_DEL_DEC_STATES ]; | ||
56 | } NSQ_del_decs_struct; | ||
57 | |||
58 | typedef struct { | ||
59 | opus_int32 Q_Q10[ NEON_MAX_DEL_DEC_STATES ]; | ||
60 | opus_int32 RD_Q10[ NEON_MAX_DEL_DEC_STATES ]; | ||
61 | opus_int32 xq_Q14[ NEON_MAX_DEL_DEC_STATES ]; | ||
62 | opus_int32 LF_AR_Q14[ NEON_MAX_DEL_DEC_STATES ]; | ||
63 | opus_int32 Diff_Q14[ NEON_MAX_DEL_DEC_STATES ]; | ||
64 | opus_int32 sLTP_shp_Q14[ NEON_MAX_DEL_DEC_STATES ]; | ||
65 | opus_int32 LPC_exc_Q14[ NEON_MAX_DEL_DEC_STATES ]; | ||
66 | } NSQ_samples_struct; | ||
67 | |||
68 | static OPUS_INLINE void silk_nsq_del_dec_scale_states_neon( | ||
69 | const silk_encoder_state *psEncC, /* I Encoder State */ | ||
70 | silk_nsq_state *NSQ, /* I/O NSQ state */ | ||
71 | NSQ_del_decs_struct psDelDec[], /* I/O Delayed decision states */ | ||
72 | const opus_int16 x16[], /* I Input */ | ||
73 | opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */ | ||
74 | const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */ | ||
75 | opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ | ||
76 | opus_int subfr, /* I Subframe number */ | ||
77 | const opus_int LTP_scale_Q14, /* I LTP state scaling */ | ||
78 | const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ | ||
79 | const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */ | ||
80 | const opus_int signal_type, /* I Signal type */ | ||
81 | const opus_int decisionDelay /* I Decision delay */ | ||
82 | ); | ||
83 | |||
84 | /******************************************/ | ||
85 | /* Noise shape quantizer for one subframe */ | ||
86 | /******************************************/ | ||
87 | static OPUS_INLINE void silk_noise_shape_quantizer_del_dec_neon( | ||
88 | silk_nsq_state *NSQ, /* I/O NSQ state */ | ||
89 | NSQ_del_decs_struct psDelDec[], /* I/O Delayed decision states */ | ||
90 | opus_int signalType, /* I Signal type */ | ||
91 | const opus_int32 x_Q10[], /* I */ | ||
92 | opus_int8 pulses[], /* O */ | ||
93 | opus_int16 xq[], /* O */ | ||
94 | opus_int32 sLTP_Q15[], /* I/O LTP filter state */ | ||
95 | opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */ | ||
96 | const opus_int16 a_Q12[], /* I Short term prediction coefs */ | ||
97 | const opus_int16 b_Q14[], /* I Long term prediction coefs */ | ||
98 | const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */ | ||
99 | opus_int lag, /* I Pitch lag */ | ||
100 | opus_int32 HarmShapeFIRPacked_Q14, /* I */ | ||
101 | opus_int Tilt_Q14, /* I Spectral tilt */ | ||
102 | opus_int32 LF_shp_Q14, /* I */ | ||
103 | opus_int32 Gain_Q16, /* I */ | ||
104 | opus_int Lambda_Q10, /* I */ | ||
105 | opus_int offset_Q10, /* I */ | ||
106 | opus_int length, /* I Input length */ | ||
107 | opus_int subfr, /* I Subframe number */ | ||
108 | opus_int shapingLPCOrder, /* I Shaping LPC filter order */ | ||
109 | opus_int predictLPCOrder, /* I Prediction filter order */ | ||
110 | opus_int warping_Q16, /* I */ | ||
111 | opus_int nStatesDelayedDecision, /* I Number of states in decision tree */ | ||
112 | opus_int *smpl_buf_idx, /* I/O Index to newest samples in buffers */ | ||
113 | opus_int decisionDelay /* I */ | ||
114 | ); | ||
115 | |||
116 | static OPUS_INLINE void copy_winner_state_kernel( | ||
117 | const NSQ_del_decs_struct *psDelDec, | ||
118 | const opus_int offset, | ||
119 | const opus_int last_smple_idx, | ||
120 | const opus_int Winner_ind, | ||
121 | const int32x2_t gain_lo_s32x2, | ||
122 | const int32x2_t gain_hi_s32x2, | ||
123 | const int32x4_t shift_s32x4, | ||
124 | int32x4_t t0_s32x4, | ||
125 | int32x4_t t1_s32x4, | ||
126 | opus_int8 *const pulses, | ||
127 | opus_int16 *pxq, | ||
128 | silk_nsq_state *NSQ | ||
129 | ) | ||
130 | { | ||
131 | int16x8_t t_s16x8; | ||
132 | int32x4_t o0_s32x4, o1_s32x4; | ||
133 | |||
134 | t0_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 0 ][ Winner_ind ], t0_s32x4, 0 ); | ||
135 | t0_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 1 ][ Winner_ind ], t0_s32x4, 1 ); | ||
136 | t0_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 2 ][ Winner_ind ], t0_s32x4, 2 ); | ||
137 | t0_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 3 ][ Winner_ind ], t0_s32x4, 3 ); | ||
138 | t1_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 4 ][ Winner_ind ], t1_s32x4, 0 ); | ||
139 | t1_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 5 ][ Winner_ind ], t1_s32x4, 1 ); | ||
140 | t1_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 6 ][ Winner_ind ], t1_s32x4, 2 ); | ||
141 | t1_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 7 ][ Winner_ind ], t1_s32x4, 3 ); | ||
142 | t_s16x8 = vcombine_s16( vrshrn_n_s32( t0_s32x4, 10 ), vrshrn_n_s32( t1_s32x4, 10 ) ); | ||
143 | vst1_s8( &pulses[ offset ], vmovn_s16( t_s16x8 ) ); | ||
144 | |||
145 | t0_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 0 ][ Winner_ind ], t0_s32x4, 0 ); | ||
146 | t0_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 1 ][ Winner_ind ], t0_s32x4, 1 ); | ||
147 | t0_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 2 ][ Winner_ind ], t0_s32x4, 2 ); | ||
148 | t0_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 3 ][ Winner_ind ], t0_s32x4, 3 ); | ||
149 | t1_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 4 ][ Winner_ind ], t1_s32x4, 0 ); | ||
150 | t1_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 5 ][ Winner_ind ], t1_s32x4, 1 ); | ||
151 | t1_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 6 ][ Winner_ind ], t1_s32x4, 2 ); | ||
152 | t1_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 7 ][ Winner_ind ], t1_s32x4, 3 ); | ||
153 | o0_s32x4 = vqdmulhq_lane_s32( t0_s32x4, gain_lo_s32x2, 0 ); | ||
154 | o1_s32x4 = vqdmulhq_lane_s32( t1_s32x4, gain_lo_s32x2, 0 ); | ||
155 | o0_s32x4 = vmlaq_lane_s32( o0_s32x4, t0_s32x4, gain_hi_s32x2, 0 ); | ||
156 | o1_s32x4 = vmlaq_lane_s32( o1_s32x4, t1_s32x4, gain_hi_s32x2, 0 ); | ||
157 | o0_s32x4 = vrshlq_s32( o0_s32x4, shift_s32x4 ); | ||
158 | o1_s32x4 = vrshlq_s32( o1_s32x4, shift_s32x4 ); | ||
159 | vst1_s16( &pxq[ offset + 0 ], vqmovn_s32( o0_s32x4 ) ); | ||
160 | vst1_s16( &pxq[ offset + 4 ], vqmovn_s32( o1_s32x4 ) ); | ||
161 | |||
162 | t0_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 0 ][ Winner_ind ], t0_s32x4, 0 ); | ||
163 | t0_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 1 ][ Winner_ind ], t0_s32x4, 1 ); | ||
164 | t0_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 2 ][ Winner_ind ], t0_s32x4, 2 ); | ||
165 | t0_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 3 ][ Winner_ind ], t0_s32x4, 3 ); | ||
166 | t1_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 4 ][ Winner_ind ], t1_s32x4, 0 ); | ||
167 | t1_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 5 ][ Winner_ind ], t1_s32x4, 1 ); | ||
168 | t1_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 6 ][ Winner_ind ], t1_s32x4, 2 ); | ||
169 | t1_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 7 ][ Winner_ind ], t1_s32x4, 3 ); | ||
170 | vst1q_s32( &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx + offset + 0 ], t0_s32x4 ); | ||
171 | vst1q_s32( &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx + offset + 4 ], t1_s32x4 ); | ||
172 | } | ||
173 | |||
174 | static OPUS_INLINE void copy_winner_state( | ||
175 | const NSQ_del_decs_struct *psDelDec, | ||
176 | const opus_int decisionDelay, | ||
177 | const opus_int smpl_buf_idx, | ||
178 | const opus_int Winner_ind, | ||
179 | const opus_int32 gain, | ||
180 | const opus_int32 shift, | ||
181 | opus_int8 *const pulses, | ||
182 | opus_int16 *pxq, | ||
183 | silk_nsq_state *NSQ | ||
184 | ) | ||
185 | { | ||
186 | opus_int i, last_smple_idx; | ||
187 | const int32x2_t gain_lo_s32x2 = vdup_n_s32( silk_LSHIFT32( gain & 0x0000FFFF, 15 ) ); | ||
188 | const int32x2_t gain_hi_s32x2 = vdup_n_s32( gain >> 16 ); | ||
189 | const int32x4_t shift_s32x4 = vdupq_n_s32( -shift ); | ||
190 | int32x4_t t0_s32x4, t1_s32x4; | ||
191 | |||
192 | t0_s32x4 = t1_s32x4 = vdupq_n_s32( 0 ); /* initialization */ | ||
193 | last_smple_idx = smpl_buf_idx + decisionDelay - 1 + DECISION_DELAY; | ||
194 | if( last_smple_idx >= DECISION_DELAY ) last_smple_idx -= DECISION_DELAY; | ||
195 | if( last_smple_idx >= DECISION_DELAY ) last_smple_idx -= DECISION_DELAY; | ||
196 | |||
197 | for( i = 0; ( i < ( decisionDelay - 7 ) ) && ( last_smple_idx >= 7 ); i += 8, last_smple_idx -= 8 ) { | ||
198 | copy_winner_state_kernel( psDelDec, i - decisionDelay, last_smple_idx, Winner_ind, gain_lo_s32x2, gain_hi_s32x2, shift_s32x4, t0_s32x4, t1_s32x4, pulses, pxq, NSQ ); | ||
199 | } | ||
200 | for( ; ( i < decisionDelay ) && ( last_smple_idx >= 0 ); i++, last_smple_idx-- ) { | ||
201 | pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDelDec->Q_Q10[ last_smple_idx ][ Winner_ind ], 10 ); | ||
202 | pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( psDelDec->Xq_Q14[ last_smple_idx ][ Winner_ind ], gain ), shift ) ); | ||
203 | NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDelDec->Shape_Q14[ last_smple_idx ][ Winner_ind ]; | ||
204 | } | ||
205 | |||
206 | last_smple_idx += DECISION_DELAY; | ||
207 | for( ; i < ( decisionDelay - 7 ); i++, last_smple_idx-- ) { | ||
208 | copy_winner_state_kernel( psDelDec, i - decisionDelay, last_smple_idx, Winner_ind, gain_lo_s32x2, gain_hi_s32x2, shift_s32x4, t0_s32x4, t1_s32x4, pulses, pxq, NSQ ); | ||
209 | } | ||
210 | for( ; i < decisionDelay; i++, last_smple_idx-- ) { | ||
211 | pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDelDec->Q_Q10[ last_smple_idx ][ Winner_ind ], 10 ); | ||
212 | pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( psDelDec->Xq_Q14[ last_smple_idx ][ Winner_ind ], gain ), shift ) ); | ||
213 | NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDelDec->Shape_Q14[ last_smple_idx ][ Winner_ind ]; | ||
214 | } | ||
215 | } | ||
216 | |||
217 | void silk_NSQ_del_dec_neon( | ||
218 | const silk_encoder_state *psEncC, /* I Encoder State */ | ||
219 | silk_nsq_state *NSQ, /* I/O NSQ state */ | ||
220 | SideInfoIndices *psIndices, /* I/O Quantization Indices */ | ||
221 | const opus_int16 x16[], /* I Input */ | ||
222 | opus_int8 pulses[], /* O Quantized pulse signal */ | ||
223 | const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ | ||
224 | const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ | ||
225 | const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ | ||
226 | const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ | ||
227 | const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ | ||
228 | const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ | ||
229 | const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ | ||
230 | const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ | ||
231 | const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ | ||
232 | const opus_int LTP_scale_Q14 /* I LTP state scaling */ | ||
233 | ) | ||
234 | { | ||
235 | #ifdef OPUS_CHECK_ASM | ||
236 | silk_nsq_state NSQ_c; | ||
237 | SideInfoIndices psIndices_c; | ||
238 | opus_int8 pulses_c[ MAX_FRAME_LENGTH ]; | ||
239 | const opus_int8 *const pulses_a = pulses; | ||
240 | |||
241 | ( void )pulses_a; | ||
242 | silk_memcpy( &NSQ_c, NSQ, sizeof( NSQ_c ) ); | ||
243 | silk_memcpy( &psIndices_c, psIndices, sizeof( psIndices_c ) ); | ||
244 | silk_memcpy( pulses_c, pulses, sizeof( pulses_c ) ); | ||
245 | silk_NSQ_del_dec_c( psEncC, &NSQ_c, &psIndices_c, x16, pulses_c, PredCoef_Q12, LTPCoef_Q14, AR_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, | ||
246 | pitchL, Lambda_Q10, LTP_scale_Q14 ); | ||
247 | #endif | ||
248 | |||
249 | /* The optimization parallelizes the different delay decision states. */ | ||
250 | if(( psEncC->nStatesDelayedDecision > NEON_MAX_DEL_DEC_STATES ) || ( psEncC->nStatesDelayedDecision <= 2 )) { | ||
251 | /* NEON intrinsics optimization now can only parallelize up to 4 delay decision states. */ | ||
252 | /* If there are more states, C function is called, and this optimization must be expanded. */ | ||
253 | /* When the number of delay decision states is less than 3, there are penalties using this */ | ||
254 | /* optimization, and C function is called. */ | ||
255 | /* When the number of delay decision states is 2, it's better to specialize another */ | ||
256 | /* structure NSQ_del_dec2_struct and optimize with shorter NEON registers. (Low priority) */ | ||
257 | silk_NSQ_del_dec_c( psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, AR_Q13, HarmShapeGain_Q14, | ||
258 | Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14 ); | ||
259 | } else { | ||
260 | opus_int i, k, lag, start_idx, LSF_interpolation_flag, Winner_ind, subfr; | ||
261 | opus_int smpl_buf_idx, decisionDelay; | ||
262 | const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13; | ||
263 | opus_int16 *pxq; | ||
264 | VARDECL( opus_int32, sLTP_Q15 ); | ||
265 | VARDECL( opus_int16, sLTP ); | ||
266 | opus_int32 HarmShapeFIRPacked_Q14; | ||
267 | opus_int offset_Q10; | ||
268 | opus_int32 RDmin_Q10, Gain_Q10; | ||
269 | VARDECL( opus_int32, x_sc_Q10 ); | ||
270 | VARDECL( opus_int32, delayedGain_Q10 ); | ||
271 | VARDECL( NSQ_del_decs_struct, psDelDec ); | ||
272 | int32x4_t t_s32x4; | ||
273 | SAVE_STACK; | ||
274 | |||
275 | /* Set unvoiced lag to the previous one, overwrite later for voiced */ | ||
276 | lag = NSQ->lagPrev; | ||
277 | |||
278 | silk_assert( NSQ->prev_gain_Q16 != 0 ); | ||
279 | |||
280 | /* Initialize delayed decision states */ | ||
281 | ALLOC( psDelDec, 1, NSQ_del_decs_struct ); | ||
282 | /* Only RandState and RD_Q10 need to be initialized to 0. */ | ||
283 | silk_memset( psDelDec->RandState, 0, sizeof( psDelDec->RandState ) ); | ||
284 | vst1q_s32( psDelDec->RD_Q10, vdupq_n_s32( 0 ) ); | ||
285 | |||
286 | for( k = 0; k < psEncC->nStatesDelayedDecision; k++ ) { | ||
287 | psDelDec->SeedInit[ k ] = psDelDec->Seed[ k ] = ( k + psIndices->Seed ) & 3; | ||
288 | } | ||
289 | vst1q_s32( psDelDec->LF_AR_Q14, vld1q_dup_s32( &NSQ->sLF_AR_shp_Q14 ) ); | ||
290 | vst1q_s32( psDelDec->Diff_Q14, vld1q_dup_s32( &NSQ->sDiff_shp_Q14 ) ); | ||
291 | vst1q_s32( psDelDec->Shape_Q14[ 0 ], vld1q_dup_s32( &NSQ->sLTP_shp_Q14[ psEncC->ltp_mem_length - 1 ] ) ); | ||
292 | for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) { | ||
293 | vst1q_s32( psDelDec->sLPC_Q14[ i ], vld1q_dup_s32( &NSQ->sLPC_Q14[ i ] ) ); | ||
294 | } | ||
295 | for( i = 0; i < (opus_int)( sizeof( NSQ->sAR2_Q14 ) / sizeof( NSQ->sAR2_Q14[ 0 ] ) ); i++ ) { | ||
296 | vst1q_s32( psDelDec->sAR2_Q14[ i ], vld1q_dup_s32( &NSQ->sAR2_Q14[ i ] ) ); | ||
297 | } | ||
298 | |||
299 | offset_Q10 = silk_Quantization_Offsets_Q10[ psIndices->signalType >> 1 ][ psIndices->quantOffsetType ]; | ||
300 | smpl_buf_idx = 0; /* index of oldest samples */ | ||
301 | |||
302 | decisionDelay = silk_min_int( DECISION_DELAY, psEncC->subfr_length ); | ||
303 | |||
304 | /* For voiced frames limit the decision delay to lower than the pitch lag */ | ||
305 | if( psIndices->signalType == TYPE_VOICED ) { | ||
306 | opus_int pitch_min = pitchL[ 0 ]; | ||
307 | for( k = 1; k < psEncC->nb_subfr; k++ ) { | ||
308 | pitch_min = silk_min_int( pitch_min, pitchL[ k ] ); | ||
309 | } | ||
310 | decisionDelay = silk_min_int( decisionDelay, pitch_min - LTP_ORDER / 2 - 1 ); | ||
311 | } else { | ||
312 | if( lag > 0 ) { | ||
313 | decisionDelay = silk_min_int( decisionDelay, lag - LTP_ORDER / 2 - 1 ); | ||
314 | } | ||
315 | } | ||
316 | |||
317 | if( psIndices->NLSFInterpCoef_Q2 == 4 ) { | ||
318 | LSF_interpolation_flag = 0; | ||
319 | } else { | ||
320 | LSF_interpolation_flag = 1; | ||
321 | } | ||
322 | |||
323 | ALLOC( sLTP_Q15, psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 ); | ||
324 | ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 ); | ||
325 | ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 ); | ||
326 | ALLOC( delayedGain_Q10, DECISION_DELAY, opus_int32 ); | ||
327 | /* Set up pointers to start of sub frame */ | ||
328 | pxq = &NSQ->xq[ psEncC->ltp_mem_length ]; | ||
329 | NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length; | ||
330 | NSQ->sLTP_buf_idx = psEncC->ltp_mem_length; | ||
331 | subfr = 0; | ||
332 | for( k = 0; k < psEncC->nb_subfr; k++ ) { | ||
333 | A_Q12 = &PredCoef_Q12[ ( ( k >> 1 ) | ( 1 - LSF_interpolation_flag ) ) * MAX_LPC_ORDER ]; | ||
334 | B_Q14 = <PCoef_Q14[ k * LTP_ORDER ]; | ||
335 | AR_shp_Q13 = &AR_Q13[ k * MAX_SHAPE_LPC_ORDER ]; | ||
336 | |||
337 | /* Noise shape parameters */ | ||
338 | silk_assert( HarmShapeGain_Q14[ k ] >= 0 ); | ||
339 | HarmShapeFIRPacked_Q14 = silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 ); | ||
340 | HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 ); | ||
341 | |||
342 | NSQ->rewhite_flag = 0; | ||
343 | if( psIndices->signalType == TYPE_VOICED ) { | ||
344 | /* Voiced */ | ||
345 | lag = pitchL[ k ]; | ||
346 | |||
347 | /* Re-whitening */ | ||
348 | if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) { | ||
349 | if( k == 2 ) { | ||
350 | /* RESET DELAYED DECISIONS */ | ||
351 | /* Find winner */ | ||
352 | int32x4_t RD_Q10_s32x4; | ||
353 | RDmin_Q10 = psDelDec->RD_Q10[ 0 ]; | ||
354 | Winner_ind = 0; | ||
355 | for( i = 1; i < psEncC->nStatesDelayedDecision; i++ ) { | ||
356 | if( psDelDec->RD_Q10[ i ] < RDmin_Q10 ) { | ||
357 | RDmin_Q10 = psDelDec->RD_Q10[ i ]; | ||
358 | Winner_ind = i; | ||
359 | } | ||
360 | } | ||
361 | psDelDec->RD_Q10[ Winner_ind ] -= ( silk_int32_MAX >> 4 ); | ||
362 | RD_Q10_s32x4 = vld1q_s32( psDelDec->RD_Q10 ); | ||
363 | RD_Q10_s32x4 = vaddq_s32( RD_Q10_s32x4, vdupq_n_s32( silk_int32_MAX >> 4 ) ); | ||
364 | vst1q_s32( psDelDec->RD_Q10, RD_Q10_s32x4 ); | ||
365 | |||
366 | /* Copy final part of signals from winner state to output and long-term filter states */ | ||
367 | copy_winner_state( psDelDec, decisionDelay, smpl_buf_idx, Winner_ind, Gains_Q16[ 1 ], 14, pulses, pxq, NSQ ); | ||
368 | |||
369 | subfr = 0; | ||
370 | } | ||
371 | |||
372 | /* Rewhiten with new A coefs */ | ||
373 | start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2; | ||
374 | silk_assert( start_idx > 0 ); | ||
375 | |||
376 | silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ], | ||
377 | A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder, psEncC->arch ); | ||
378 | |||
379 | NSQ->sLTP_buf_idx = psEncC->ltp_mem_length; | ||
380 | NSQ->rewhite_flag = 1; | ||
381 | } | ||
382 | } | ||
383 | |||
384 | silk_nsq_del_dec_scale_states_neon( psEncC, NSQ, psDelDec, x16, x_sc_Q10, sLTP, sLTP_Q15, k, | ||
385 | LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType, decisionDelay ); | ||
386 | |||
387 | silk_noise_shape_quantizer_del_dec_neon( NSQ, psDelDec, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15, | ||
388 | delayedGain_Q10, A_Q12, B_Q14, AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], | ||
389 | Gains_Q16[ k ], Lambda_Q10, offset_Q10, psEncC->subfr_length, subfr++, psEncC->shapingLPCOrder, | ||
390 | psEncC->predictLPCOrder, psEncC->warping_Q16, psEncC->nStatesDelayedDecision, &smpl_buf_idx, decisionDelay ); | ||
391 | |||
392 | x16 += psEncC->subfr_length; | ||
393 | pulses += psEncC->subfr_length; | ||
394 | pxq += psEncC->subfr_length; | ||
395 | } | ||
396 | |||
397 | /* Find winner */ | ||
398 | RDmin_Q10 = psDelDec->RD_Q10[ 0 ]; | ||
399 | Winner_ind = 0; | ||
400 | for( k = 1; k < psEncC->nStatesDelayedDecision; k++ ) { | ||
401 | if( psDelDec->RD_Q10[ k ] < RDmin_Q10 ) { | ||
402 | RDmin_Q10 = psDelDec->RD_Q10[ k ]; | ||
403 | Winner_ind = k; | ||
404 | } | ||
405 | } | ||
406 | |||
407 | /* Copy final part of signals from winner state to output and long-term filter states */ | ||
408 | psIndices->Seed = psDelDec->SeedInit[ Winner_ind ]; | ||
409 | Gain_Q10 = silk_RSHIFT32( Gains_Q16[ psEncC->nb_subfr - 1 ], 6 ); | ||
410 | copy_winner_state( psDelDec, decisionDelay, smpl_buf_idx, Winner_ind, Gain_Q10, 8, pulses, pxq, NSQ ); | ||
411 | |||
412 | t_s32x4 = vdupq_n_s32( 0 ); /* initialization */ | ||
413 | for( i = 0; i < ( NSQ_LPC_BUF_LENGTH - 3 ); i += 4 ) { | ||
414 | t_s32x4 = vld1q_lane_s32( &psDelDec->sLPC_Q14[ i + 0 ][ Winner_ind ], t_s32x4, 0 ); | ||
415 | t_s32x4 = vld1q_lane_s32( &psDelDec->sLPC_Q14[ i + 1 ][ Winner_ind ], t_s32x4, 1 ); | ||
416 | t_s32x4 = vld1q_lane_s32( &psDelDec->sLPC_Q14[ i + 2 ][ Winner_ind ], t_s32x4, 2 ); | ||
417 | t_s32x4 = vld1q_lane_s32( &psDelDec->sLPC_Q14[ i + 3 ][ Winner_ind ], t_s32x4, 3 ); | ||
418 | vst1q_s32( &NSQ->sLPC_Q14[ i ], t_s32x4 ); | ||
419 | } | ||
420 | |||
421 | for( ; i < NSQ_LPC_BUF_LENGTH; i++ ) { | ||
422 | NSQ->sLPC_Q14[ i ] = psDelDec->sLPC_Q14[ i ][ Winner_ind ]; | ||
423 | } | ||
424 | |||
425 | for( i = 0; i < (opus_int)( sizeof( NSQ->sAR2_Q14 ) / sizeof( NSQ->sAR2_Q14[ 0 ] ) - 3 ); i += 4 ) { | ||
426 | t_s32x4 = vld1q_lane_s32( &psDelDec->sAR2_Q14[ i + 0 ][ Winner_ind ], t_s32x4, 0 ); | ||
427 | t_s32x4 = vld1q_lane_s32( &psDelDec->sAR2_Q14[ i + 1 ][ Winner_ind ], t_s32x4, 1 ); | ||
428 | t_s32x4 = vld1q_lane_s32( &psDelDec->sAR2_Q14[ i + 2 ][ Winner_ind ], t_s32x4, 2 ); | ||
429 | t_s32x4 = vld1q_lane_s32( &psDelDec->sAR2_Q14[ i + 3 ][ Winner_ind ], t_s32x4, 3 ); | ||
430 | vst1q_s32( &NSQ->sAR2_Q14[ i ], t_s32x4 ); | ||
431 | } | ||
432 | |||
433 | for( ; i < (opus_int)( sizeof( NSQ->sAR2_Q14 ) / sizeof( NSQ->sAR2_Q14[ 0 ] ) ); i++ ) { | ||
434 | NSQ->sAR2_Q14[ i ] = psDelDec->sAR2_Q14[ i ][ Winner_ind ]; | ||
435 | } | ||
436 | |||
437 | /* Update states */ | ||
438 | NSQ->sLF_AR_shp_Q14 = psDelDec->LF_AR_Q14[ Winner_ind ]; | ||
439 | NSQ->sDiff_shp_Q14 = psDelDec->Diff_Q14[ Winner_ind ]; | ||
440 | NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ]; | ||
441 | |||
442 | /* Save quantized speech signal */ | ||
443 | silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) ); | ||
444 | silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) ); | ||
445 | RESTORE_STACK; | ||
446 | } | ||
447 | |||
448 | #ifdef OPUS_CHECK_ASM | ||
449 | silk_assert( !memcmp( &NSQ_c, NSQ, sizeof( NSQ_c ) ) ); | ||
450 | silk_assert( !memcmp( &psIndices_c, psIndices, sizeof( psIndices_c ) ) ); | ||
451 | silk_assert( !memcmp( pulses_c, pulses_a, sizeof( pulses_c ) ) ); | ||
452 | #endif | ||
453 | } | ||
454 | |||
455 | /******************************************/ | ||
456 | /* Noise shape quantizer for one subframe */ | ||
457 | /******************************************/ | ||
458 | /* Note: Function silk_short_prediction_create_arch_coef_neon() defined in NSQ_neon.h is actually a hacking C function. */ | ||
459 | /* Therefore here we append "_local" to the NEON function name to avoid confusion. */ | ||
460 | static OPUS_INLINE void silk_short_prediction_create_arch_coef_neon_local(opus_int32 *out, const opus_int16 *in, opus_int order) | ||
461 | { | ||
462 | int16x8_t t_s16x8; | ||
463 | int32x4_t t0_s32x4, t1_s32x4, t2_s32x4, t3_s32x4; | ||
464 | silk_assert( order == 10 || order == 16 ); | ||
465 | |||
466 | t_s16x8 = vld1q_s16( in + 0 ); /* 7 6 5 4 3 2 1 0 */ | ||
467 | t_s16x8 = vrev64q_s16( t_s16x8 ); /* 4 5 6 7 0 1 2 3 */ | ||
468 | t2_s32x4 = vshll_n_s16( vget_high_s16( t_s16x8 ), 15 ); /* 4 5 6 7 */ | ||
469 | t3_s32x4 = vshll_n_s16( vget_low_s16( t_s16x8 ), 15 ); /* 0 1 2 3 */ | ||
470 | |||
471 | if( order == 16 ) { | ||
472 | t_s16x8 = vld1q_s16( in + 8 ); /* F E D C B A 9 8 */ | ||
473 | t_s16x8 = vrev64q_s16( t_s16x8 ); /* C D E F 8 9 A B */ | ||
474 | t0_s32x4 = vshll_n_s16( vget_high_s16( t_s16x8 ), 15 ); /* C D E F */ | ||
475 | t1_s32x4 = vshll_n_s16( vget_low_s16( t_s16x8 ), 15 ); /* 8 9 A B */ | ||
476 | } else { | ||
477 | int16x4_t t_s16x4; | ||
478 | |||
479 | t0_s32x4 = vdupq_n_s32( 0 ); /* zero zero zero zero */ | ||
480 | t_s16x4 = vld1_s16( in + 6 ); /* 9 8 7 6 */ | ||
481 | t_s16x4 = vrev64_s16( t_s16x4 ); /* 6 7 8 9 */ | ||
482 | t1_s32x4 = vshll_n_s16( t_s16x4, 15 ); | ||
483 | t1_s32x4 = vcombine_s32( vget_low_s32(t0_s32x4), vget_low_s32( t1_s32x4 ) ); /* 8 9 zero zero */ | ||
484 | } | ||
485 | vst1q_s32( out + 0, t0_s32x4 ); | ||
486 | vst1q_s32( out + 4, t1_s32x4 ); | ||
487 | vst1q_s32( out + 8, t2_s32x4 ); | ||
488 | vst1q_s32( out + 12, t3_s32x4 ); | ||
489 | } | ||
490 | |||
491 | static OPUS_INLINE int32x4_t silk_SMLAWB_lane0_neon( | ||
492 | const int32x4_t out_s32x4, | ||
493 | const int32x4_t in_s32x4, | ||
494 | const int32x2_t coef_s32x2 | ||
495 | ) | ||
496 | { | ||
497 | return vaddq_s32( out_s32x4, vqdmulhq_lane_s32( in_s32x4, coef_s32x2, 0 ) ); | ||
498 | } | ||
499 | |||
500 | static OPUS_INLINE int32x4_t silk_SMLAWB_lane1_neon( | ||
501 | const int32x4_t out_s32x4, | ||
502 | const int32x4_t in_s32x4, | ||
503 | const int32x2_t coef_s32x2 | ||
504 | ) | ||
505 | { | ||
506 | return vaddq_s32( out_s32x4, vqdmulhq_lane_s32( in_s32x4, coef_s32x2, 1 ) ); | ||
507 | } | ||
508 | |||
509 | /* Note: This function has different return value than silk_noise_shape_quantizer_short_prediction_neon(). */ | ||
510 | /* Therefore here we append "_local" to the function name to avoid confusion. */ | ||
511 | static OPUS_INLINE int32x4_t silk_noise_shape_quantizer_short_prediction_neon_local(const opus_int32 *buf32, const opus_int32 *a_Q12_arch, opus_int order) | ||
512 | { | ||
513 | const int32x4_t a_Q12_arch0_s32x4 = vld1q_s32( a_Q12_arch + 0 ); | ||
514 | const int32x4_t a_Q12_arch1_s32x4 = vld1q_s32( a_Q12_arch + 4 ); | ||
515 | const int32x4_t a_Q12_arch2_s32x4 = vld1q_s32( a_Q12_arch + 8 ); | ||
516 | const int32x4_t a_Q12_arch3_s32x4 = vld1q_s32( a_Q12_arch + 12 ); | ||
517 | int32x4_t LPC_pred_Q14_s32x4; | ||
518 | |||
519 | silk_assert( order == 10 || order == 16 ); | ||
520 | /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ | ||
521 | LPC_pred_Q14_s32x4 = vdupq_n_s32( silk_RSHIFT( order, 1 ) ); | ||
522 | LPC_pred_Q14_s32x4 = silk_SMLAWB_lane0_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 0 * NEON_MAX_DEL_DEC_STATES ), vget_low_s32( a_Q12_arch0_s32x4 ) ); | ||
523 | LPC_pred_Q14_s32x4 = silk_SMLAWB_lane1_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 1 * NEON_MAX_DEL_DEC_STATES ), vget_low_s32( a_Q12_arch0_s32x4 ) ); | ||
524 | LPC_pred_Q14_s32x4 = silk_SMLAWB_lane0_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 2 * NEON_MAX_DEL_DEC_STATES ), vget_high_s32( a_Q12_arch0_s32x4 ) ); | ||
525 | LPC_pred_Q14_s32x4 = silk_SMLAWB_lane1_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 3 * NEON_MAX_DEL_DEC_STATES ), vget_high_s32( a_Q12_arch0_s32x4 ) ); | ||
526 | LPC_pred_Q14_s32x4 = silk_SMLAWB_lane0_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 4 * NEON_MAX_DEL_DEC_STATES ), vget_low_s32( a_Q12_arch1_s32x4 ) ); | ||
527 | LPC_pred_Q14_s32x4 = silk_SMLAWB_lane1_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 5 * NEON_MAX_DEL_DEC_STATES ), vget_low_s32( a_Q12_arch1_s32x4 ) ); | ||
528 | LPC_pred_Q14_s32x4 = silk_SMLAWB_lane0_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 6 * NEON_MAX_DEL_DEC_STATES ), vget_high_s32( a_Q12_arch1_s32x4 ) ); | ||
529 | LPC_pred_Q14_s32x4 = silk_SMLAWB_lane1_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 7 * NEON_MAX_DEL_DEC_STATES ), vget_high_s32( a_Q12_arch1_s32x4 ) ); | ||
530 | LPC_pred_Q14_s32x4 = silk_SMLAWB_lane0_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 8 * NEON_MAX_DEL_DEC_STATES ), vget_low_s32( a_Q12_arch2_s32x4 ) ); | ||
531 | LPC_pred_Q14_s32x4 = silk_SMLAWB_lane1_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 9 * NEON_MAX_DEL_DEC_STATES ), vget_low_s32( a_Q12_arch2_s32x4 ) ); | ||
532 | LPC_pred_Q14_s32x4 = silk_SMLAWB_lane0_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 10 * NEON_MAX_DEL_DEC_STATES ), vget_high_s32( a_Q12_arch2_s32x4 ) ); | ||
533 | LPC_pred_Q14_s32x4 = silk_SMLAWB_lane1_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 11 * NEON_MAX_DEL_DEC_STATES ), vget_high_s32( a_Q12_arch2_s32x4 ) ); | ||
534 | LPC_pred_Q14_s32x4 = silk_SMLAWB_lane0_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 12 * NEON_MAX_DEL_DEC_STATES ), vget_low_s32( a_Q12_arch3_s32x4 ) ); | ||
535 | LPC_pred_Q14_s32x4 = silk_SMLAWB_lane1_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 13 * NEON_MAX_DEL_DEC_STATES ), vget_low_s32( a_Q12_arch3_s32x4 ) ); | ||
536 | LPC_pred_Q14_s32x4 = silk_SMLAWB_lane0_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 14 * NEON_MAX_DEL_DEC_STATES ), vget_high_s32( a_Q12_arch3_s32x4 ) ); | ||
537 | LPC_pred_Q14_s32x4 = silk_SMLAWB_lane1_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 15 * NEON_MAX_DEL_DEC_STATES ), vget_high_s32( a_Q12_arch3_s32x4 ) ); | ||
538 | |||
539 | return LPC_pred_Q14_s32x4; | ||
540 | } | ||
541 | |||
542 | static OPUS_INLINE void silk_noise_shape_quantizer_del_dec_neon( | ||
543 | silk_nsq_state *NSQ, /* I/O NSQ state */ | ||
544 | NSQ_del_decs_struct psDelDec[], /* I/O Delayed decision states */ | ||
545 | opus_int signalType, /* I Signal type */ | ||
546 | const opus_int32 x_Q10[], /* I */ | ||
547 | opus_int8 pulses[], /* O */ | ||
548 | opus_int16 xq[], /* O */ | ||
549 | opus_int32 sLTP_Q15[], /* I/O LTP filter state */ | ||
550 | opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */ | ||
551 | const opus_int16 a_Q12[], /* I Short term prediction coefs */ | ||
552 | const opus_int16 b_Q14[], /* I Long term prediction coefs */ | ||
553 | const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */ | ||
554 | opus_int lag, /* I Pitch lag */ | ||
555 | opus_int32 HarmShapeFIRPacked_Q14, /* I */ | ||
556 | opus_int Tilt_Q14, /* I Spectral tilt */ | ||
557 | opus_int32 LF_shp_Q14, /* I */ | ||
558 | opus_int32 Gain_Q16, /* I */ | ||
559 | opus_int Lambda_Q10, /* I */ | ||
560 | opus_int offset_Q10, /* I */ | ||
561 | opus_int length, /* I Input length */ | ||
562 | opus_int subfr, /* I Subframe number */ | ||
563 | opus_int shapingLPCOrder, /* I Shaping LPC filter order */ | ||
564 | opus_int predictLPCOrder, /* I Prediction filter order */ | ||
565 | opus_int warping_Q16, /* I */ | ||
566 | opus_int nStatesDelayedDecision, /* I Number of states in decision tree */ | ||
567 | opus_int *smpl_buf_idx, /* I/O Index to newest samples in buffers */ | ||
568 | opus_int decisionDelay /* I */ | ||
569 | ) | ||
570 | { | ||
571 | opus_int i, j, k, Winner_ind, RDmin_ind, RDmax_ind, last_smple_idx; | ||
572 | opus_int32 Winner_rand_state; | ||
573 | opus_int32 LTP_pred_Q14, n_LTP_Q14; | ||
574 | opus_int32 RDmin_Q10, RDmax_Q10; | ||
575 | opus_int32 Gain_Q10; | ||
576 | opus_int32 *pred_lag_ptr, *shp_lag_ptr; | ||
577 | opus_int32 a_Q12_arch[MAX_LPC_ORDER]; | ||
578 | const int32x2_t warping_Q16_s32x2 = vdup_n_s32( silk_LSHIFT32( warping_Q16, 16 ) >> 1 ); | ||
579 | const opus_int32 LF_shp_Q29 = silk_LSHIFT32( LF_shp_Q14, 16 ) >> 1; | ||
580 | opus_int32 AR_shp_Q28[ MAX_SHAPE_LPC_ORDER ]; | ||
581 | const uint32x4_t rand_multiplier_u32x4 = vdupq_n_u32( RAND_MULTIPLIER ); | ||
582 | const uint32x4_t rand_increment_u32x4 = vdupq_n_u32( RAND_INCREMENT ); | ||
583 | |||
584 | VARDECL( NSQ_samples_struct, psSampleState ); | ||
585 | SAVE_STACK; | ||
586 | |||
587 | silk_assert( nStatesDelayedDecision > 0 ); | ||
588 | silk_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */ | ||
589 | ALLOC( psSampleState, 2, NSQ_samples_struct ); | ||
590 | |||
591 | shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ]; | ||
592 | pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ]; | ||
593 | Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 ); | ||
594 | |||
595 | for( i = 0; i < ( MAX_SHAPE_LPC_ORDER - 7 ); i += 8 ) { | ||
596 | const int16x8_t t_s16x8 = vld1q_s16( AR_shp_Q13 + i ); | ||
597 | vst1q_s32( AR_shp_Q28 + i + 0, vshll_n_s16( vget_low_s16( t_s16x8 ), 15 ) ); | ||
598 | vst1q_s32( AR_shp_Q28 + i + 4, vshll_n_s16( vget_high_s16( t_s16x8 ), 15 ) ); | ||
599 | } | ||
600 | |||
601 | for( ; i < MAX_SHAPE_LPC_ORDER; i++ ) { | ||
602 | AR_shp_Q28[i] = silk_LSHIFT32( AR_shp_Q13[i], 15 ); | ||
603 | } | ||
604 | |||
605 | silk_short_prediction_create_arch_coef_neon_local( a_Q12_arch, a_Q12, predictLPCOrder ); | ||
606 | |||
607 | for( i = 0; i < length; i++ ) { | ||
608 | int32x4_t Seed_s32x4, LPC_pred_Q14_s32x4; | ||
609 | int32x4_t sign_s32x4, tmp1_s32x4, tmp2_s32x4; | ||
610 | int32x4_t n_AR_Q14_s32x4, n_LF_Q14_s32x4; | ||
611 | int32x2_t AR_shp_Q28_s32x2; | ||
612 | int16x4_t r_Q10_s16x4, rr_Q10_s16x4; | ||
613 | |||
614 | /* Perform common calculations used in all states */ | ||
615 | |||
616 | /* Long-term prediction */ | ||
617 | if( signalType == TYPE_VOICED ) { | ||
618 | /* Unrolled loop */ | ||
619 | /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ | ||
620 | LTP_pred_Q14 = 2; | ||
621 | LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ 0 ], b_Q14[ 0 ] ); | ||
622 | LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -1 ], b_Q14[ 1 ] ); | ||
623 | LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -2 ], b_Q14[ 2 ] ); | ||
624 | LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -3 ], b_Q14[ 3 ] ); | ||
625 | LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], b_Q14[ 4 ] ); | ||
626 | LTP_pred_Q14 = silk_LSHIFT( LTP_pred_Q14, 1 ); /* Q13 -> Q14 */ | ||
627 | pred_lag_ptr++; | ||
628 | } else { | ||
629 | LTP_pred_Q14 = 0; | ||
630 | } | ||
631 | |||
632 | /* Long-term shaping */ | ||
633 | if( lag > 0 ) { | ||
634 | /* Symmetric, packed FIR coefficients */ | ||
635 | n_LTP_Q14 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 ); | ||
636 | n_LTP_Q14 = silk_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 ); | ||
637 | n_LTP_Q14 = silk_SUB_LSHIFT32( LTP_pred_Q14, n_LTP_Q14, 2 ); /* Q12 -> Q14 */ | ||
638 | shp_lag_ptr++; | ||
639 | } else { | ||
640 | n_LTP_Q14 = 0; | ||
641 | } | ||
642 | |||
643 | /* Generate dither */ | ||
644 | Seed_s32x4 = vld1q_s32( psDelDec->Seed ); | ||
645 | Seed_s32x4 = vreinterpretq_s32_u32( vmlaq_u32( rand_increment_u32x4, vreinterpretq_u32_s32( Seed_s32x4 ), rand_multiplier_u32x4 ) ); | ||
646 | vst1q_s32( psDelDec->Seed, Seed_s32x4 ); | ||
647 | |||
648 | /* Short-term prediction */ | ||
649 | LPC_pred_Q14_s32x4 = silk_noise_shape_quantizer_short_prediction_neon_local(psDelDec->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 16 + i ], a_Q12_arch, predictLPCOrder); | ||
650 | LPC_pred_Q14_s32x4 = vshlq_n_s32( LPC_pred_Q14_s32x4, 4 ); /* Q10 -> Q14 */ | ||
651 | |||
652 | /* Noise shape feedback */ | ||
653 | /* Output of lowpass section */ | ||
654 | tmp2_s32x4 = silk_SMLAWB_lane0_neon( vld1q_s32( psDelDec->Diff_Q14 ), vld1q_s32( psDelDec->sAR2_Q14[ 0 ] ), warping_Q16_s32x2 ); | ||
655 | /* Output of allpass section */ | ||
656 | tmp1_s32x4 = vsubq_s32( vld1q_s32( psDelDec->sAR2_Q14[ 1 ] ), tmp2_s32x4 ); | ||
657 | tmp1_s32x4 = silk_SMLAWB_lane0_neon( vld1q_s32( psDelDec->sAR2_Q14[ 0 ] ), tmp1_s32x4, warping_Q16_s32x2 ); | ||
658 | vst1q_s32( psDelDec->sAR2_Q14[ 0 ], tmp2_s32x4 ); | ||
659 | AR_shp_Q28_s32x2 = vld1_s32( AR_shp_Q28 ); | ||
660 | n_AR_Q14_s32x4 = vaddq_s32( vdupq_n_s32( silk_RSHIFT( shapingLPCOrder, 1 ) ), vqdmulhq_lane_s32( tmp2_s32x4, AR_shp_Q28_s32x2, 0 ) ); | ||
661 | |||
662 | /* Loop over allpass sections */ | ||
663 | for( j = 2; j < shapingLPCOrder; j += 2 ) { | ||
664 | /* Output of allpass section */ | ||
665 | tmp2_s32x4 = vsubq_s32( vld1q_s32( psDelDec->sAR2_Q14[ j + 0 ] ), tmp1_s32x4 ); | ||
666 | tmp2_s32x4 = silk_SMLAWB_lane0_neon( vld1q_s32( psDelDec->sAR2_Q14[ j - 1 ] ), tmp2_s32x4, warping_Q16_s32x2 ); | ||
667 | vst1q_s32( psDelDec->sAR2_Q14[ j - 1 ], tmp1_s32x4 ); | ||
668 | n_AR_Q14_s32x4 = vaddq_s32( n_AR_Q14_s32x4, vqdmulhq_lane_s32( tmp1_s32x4, AR_shp_Q28_s32x2, 1 ) ); | ||
669 | /* Output of allpass section */ | ||
670 | tmp1_s32x4 = vsubq_s32( vld1q_s32( psDelDec->sAR2_Q14[ j + 1 ] ), tmp2_s32x4 ); | ||
671 | tmp1_s32x4 = silk_SMLAWB_lane0_neon( vld1q_s32( psDelDec->sAR2_Q14[ j + 0 ] ), tmp1_s32x4, warping_Q16_s32x2 ); | ||
672 | vst1q_s32( psDelDec->sAR2_Q14[ j + 0 ], tmp2_s32x4 ); | ||
673 | AR_shp_Q28_s32x2 = vld1_s32( &AR_shp_Q28[ j ] ); | ||
674 | n_AR_Q14_s32x4 = vaddq_s32( n_AR_Q14_s32x4, vqdmulhq_lane_s32( tmp2_s32x4, AR_shp_Q28_s32x2, 0 ) ); | ||
675 | } | ||
676 | vst1q_s32( psDelDec->sAR2_Q14[ shapingLPCOrder - 1 ], tmp1_s32x4 ); | ||
677 | n_AR_Q14_s32x4 = vaddq_s32( n_AR_Q14_s32x4, vqdmulhq_lane_s32( tmp1_s32x4, AR_shp_Q28_s32x2, 1 ) ); | ||
678 | n_AR_Q14_s32x4 = vshlq_n_s32( n_AR_Q14_s32x4, 1 ); /* Q11 -> Q12 */ | ||
679 | n_AR_Q14_s32x4 = vaddq_s32( n_AR_Q14_s32x4, vqdmulhq_n_s32( vld1q_s32( psDelDec->LF_AR_Q14 ), silk_LSHIFT32( Tilt_Q14, 16 ) >> 1 ) ); /* Q12 */ | ||
680 | n_AR_Q14_s32x4 = vshlq_n_s32( n_AR_Q14_s32x4, 2 ); /* Q12 -> Q14 */ | ||
681 | n_LF_Q14_s32x4 = vqdmulhq_n_s32( vld1q_s32( psDelDec->Shape_Q14[ *smpl_buf_idx ] ), LF_shp_Q29 ); /* Q12 */ | ||
682 | n_LF_Q14_s32x4 = vaddq_s32( n_LF_Q14_s32x4, vqdmulhq_n_s32( vld1q_s32( psDelDec->LF_AR_Q14 ), silk_LSHIFT32( LF_shp_Q14 >> 16 , 15 ) ) ); /* Q12 */ | ||
683 | n_LF_Q14_s32x4 = vshlq_n_s32( n_LF_Q14_s32x4, 2 ); /* Q12 -> Q14 */ | ||
684 | |||
685 | /* Input minus prediction plus noise feedback */ | ||
686 | /* r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP */ | ||
687 | tmp1_s32x4 = vaddq_s32( n_AR_Q14_s32x4, n_LF_Q14_s32x4 ); /* Q14 */ | ||
688 | tmp2_s32x4 = vaddq_s32( vdupq_n_s32( n_LTP_Q14 ), LPC_pred_Q14_s32x4 ); /* Q13 */ | ||
689 | tmp1_s32x4 = vsubq_s32( tmp2_s32x4, tmp1_s32x4 ); /* Q13 */ | ||
690 | tmp1_s32x4 = vrshrq_n_s32( tmp1_s32x4, 4 ); /* Q10 */ | ||
691 | tmp1_s32x4 = vsubq_s32( vdupq_n_s32( x_Q10[ i ] ), tmp1_s32x4 ); /* residual error Q10 */ | ||
692 | |||
693 | /* Flip sign depending on dither */ | ||
694 | sign_s32x4 = vreinterpretq_s32_u32( vcltq_s32( Seed_s32x4, vdupq_n_s32( 0 ) ) ); | ||
695 | tmp1_s32x4 = veorq_s32( tmp1_s32x4, sign_s32x4 ); | ||
696 | tmp1_s32x4 = vsubq_s32( tmp1_s32x4, sign_s32x4 ); | ||
697 | tmp1_s32x4 = vmaxq_s32( tmp1_s32x4, vdupq_n_s32( -( 31 << 10 ) ) ); | ||
698 | tmp1_s32x4 = vminq_s32( tmp1_s32x4, vdupq_n_s32( 30 << 10 ) ); | ||
699 | r_Q10_s16x4 = vmovn_s32( tmp1_s32x4 ); | ||
700 | |||
701 | /* Find two quantization level candidates and measure their rate-distortion */ | ||
702 | { | ||
703 | int16x4_t q1_Q10_s16x4 = vsub_s16( r_Q10_s16x4, vdup_n_s16( offset_Q10 ) ); | ||
704 | int16x4_t q1_Q0_s16x4 = vshr_n_s16( q1_Q10_s16x4, 10 ); | ||
705 | int16x4_t q2_Q10_s16x4; | ||
706 | int32x4_t rd1_Q10_s32x4, rd2_Q10_s32x4; | ||
707 | uint32x4_t t_u32x4; | ||
708 | |||
709 | if( Lambda_Q10 > 2048 ) { | ||
710 | /* For aggressive RDO, the bias becomes more than one pulse. */ | ||
711 | const int rdo_offset = Lambda_Q10/2 - 512; | ||
712 | const uint16x4_t greaterThanRdo = vcgt_s16( q1_Q10_s16x4, vdup_n_s16( rdo_offset ) ); | ||
713 | const uint16x4_t lessThanMinusRdo = vclt_s16( q1_Q10_s16x4, vdup_n_s16( -rdo_offset ) ); | ||
714 | /* If Lambda_Q10 > 32767, then q1_Q0, q1_Q10 and q2_Q10 must change to 32-bit. */ | ||
715 | silk_assert( Lambda_Q10 <= 32767 ); | ||
716 | |||
717 | q1_Q0_s16x4 = vreinterpret_s16_u16( vclt_s16( q1_Q10_s16x4, vdup_n_s16( 0 ) ) ); | ||
718 | q1_Q0_s16x4 = vbsl_s16( greaterThanRdo, vsub_s16( q1_Q10_s16x4, vdup_n_s16( rdo_offset ) ), q1_Q0_s16x4 ); | ||
719 | q1_Q0_s16x4 = vbsl_s16( lessThanMinusRdo, vadd_s16( q1_Q10_s16x4, vdup_n_s16( rdo_offset ) ), q1_Q0_s16x4 ); | ||
720 | q1_Q0_s16x4 = vshr_n_s16( q1_Q0_s16x4, 10 ); | ||
721 | } | ||
722 | { | ||
723 | const uint16x4_t equal0_u16x4 = vceq_s16( q1_Q0_s16x4, vdup_n_s16( 0 ) ); | ||
724 | const uint16x4_t equalMinus1_u16x4 = vceq_s16( q1_Q0_s16x4, vdup_n_s16( -1 ) ); | ||
725 | const uint16x4_t lessThanMinus1_u16x4 = vclt_s16( q1_Q0_s16x4, vdup_n_s16( -1 ) ); | ||
726 | int16x4_t tmp1_s16x4, tmp2_s16x4; | ||
727 | |||
728 | q1_Q10_s16x4 = vshl_n_s16( q1_Q0_s16x4, 10 ); | ||
729 | tmp1_s16x4 = vadd_s16( q1_Q10_s16x4, vdup_n_s16( offset_Q10 - QUANT_LEVEL_ADJUST_Q10 ) ); | ||
730 | q1_Q10_s16x4 = vadd_s16( q1_Q10_s16x4, vdup_n_s16( offset_Q10 + QUANT_LEVEL_ADJUST_Q10 ) ); | ||
731 | q1_Q10_s16x4 = vbsl_s16( lessThanMinus1_u16x4, q1_Q10_s16x4, tmp1_s16x4 ); | ||
732 | q1_Q10_s16x4 = vbsl_s16( equal0_u16x4, vdup_n_s16( offset_Q10 ), q1_Q10_s16x4 ); | ||
733 | q1_Q10_s16x4 = vbsl_s16( equalMinus1_u16x4, vdup_n_s16( offset_Q10 - ( 1024 - QUANT_LEVEL_ADJUST_Q10 ) ), q1_Q10_s16x4 ); | ||
734 | q2_Q10_s16x4 = vadd_s16( q1_Q10_s16x4, vdup_n_s16( 1024 ) ); | ||
735 | q2_Q10_s16x4 = vbsl_s16( equal0_u16x4, vdup_n_s16( offset_Q10 + 1024 - QUANT_LEVEL_ADJUST_Q10 ), q2_Q10_s16x4 ); | ||
736 | q2_Q10_s16x4 = vbsl_s16( equalMinus1_u16x4, vdup_n_s16( offset_Q10 ), q2_Q10_s16x4 ); | ||
737 | tmp1_s16x4 = q1_Q10_s16x4; | ||
738 | tmp2_s16x4 = q2_Q10_s16x4; | ||
739 | tmp1_s16x4 = vbsl_s16( vorr_u16( equalMinus1_u16x4, lessThanMinus1_u16x4 ), vneg_s16( tmp1_s16x4 ), tmp1_s16x4 ); | ||
740 | tmp2_s16x4 = vbsl_s16( lessThanMinus1_u16x4, vneg_s16( tmp2_s16x4 ), tmp2_s16x4 ); | ||
741 | rd1_Q10_s32x4 = vmull_s16( tmp1_s16x4, vdup_n_s16( Lambda_Q10 ) ); | ||
742 | rd2_Q10_s32x4 = vmull_s16( tmp2_s16x4, vdup_n_s16( Lambda_Q10 ) ); | ||
743 | } | ||
744 | |||
745 | rr_Q10_s16x4 = vsub_s16( r_Q10_s16x4, q1_Q10_s16x4 ); | ||
746 | rd1_Q10_s32x4 = vmlal_s16( rd1_Q10_s32x4, rr_Q10_s16x4, rr_Q10_s16x4 ); | ||
747 | rd1_Q10_s32x4 = vshrq_n_s32( rd1_Q10_s32x4, 10 ); | ||
748 | |||
749 | rr_Q10_s16x4 = vsub_s16( r_Q10_s16x4, q2_Q10_s16x4 ); | ||
750 | rd2_Q10_s32x4 = vmlal_s16( rd2_Q10_s32x4, rr_Q10_s16x4, rr_Q10_s16x4 ); | ||
751 | rd2_Q10_s32x4 = vshrq_n_s32( rd2_Q10_s32x4, 10 ); | ||
752 | |||
753 | tmp2_s32x4 = vld1q_s32( psDelDec->RD_Q10 ); | ||
754 | tmp1_s32x4 = vaddq_s32( tmp2_s32x4, vminq_s32( rd1_Q10_s32x4, rd2_Q10_s32x4 ) ); | ||
755 | tmp2_s32x4 = vaddq_s32( tmp2_s32x4, vmaxq_s32( rd1_Q10_s32x4, rd2_Q10_s32x4 ) ); | ||
756 | vst1q_s32( psSampleState[ 0 ].RD_Q10, tmp1_s32x4 ); | ||
757 | vst1q_s32( psSampleState[ 1 ].RD_Q10, tmp2_s32x4 ); | ||
758 | t_u32x4 = vcltq_s32( rd1_Q10_s32x4, rd2_Q10_s32x4 ); | ||
759 | tmp1_s32x4 = vbslq_s32( t_u32x4, vmovl_s16( q1_Q10_s16x4 ), vmovl_s16( q2_Q10_s16x4 ) ); | ||
760 | tmp2_s32x4 = vbslq_s32( t_u32x4, vmovl_s16( q2_Q10_s16x4 ), vmovl_s16( q1_Q10_s16x4 ) ); | ||
761 | vst1q_s32( psSampleState[ 0 ].Q_Q10, tmp1_s32x4 ); | ||
762 | vst1q_s32( psSampleState[ 1 ].Q_Q10, tmp2_s32x4 ); | ||
763 | } | ||
764 | |||
765 | { | ||
766 | /* Update states for best quantization */ | ||
767 | int32x4_t exc_Q14_s32x4, LPC_exc_Q14_s32x4, xq_Q14_s32x4, sLF_AR_shp_Q14_s32x4; | ||
768 | |||
769 | /* Quantized excitation */ | ||
770 | exc_Q14_s32x4 = vshlq_n_s32( tmp1_s32x4, 4 ); | ||
771 | exc_Q14_s32x4 = veorq_s32( exc_Q14_s32x4, sign_s32x4 ); | ||
772 | exc_Q14_s32x4 = vsubq_s32( exc_Q14_s32x4, sign_s32x4 ); | ||
773 | |||
774 | /* Add predictions */ | ||
775 | LPC_exc_Q14_s32x4 = vaddq_s32( exc_Q14_s32x4, vdupq_n_s32( LTP_pred_Q14 ) ); | ||
776 | xq_Q14_s32x4 = vaddq_s32( LPC_exc_Q14_s32x4, LPC_pred_Q14_s32x4 ); | ||
777 | |||
778 | /* Update states */ | ||
779 | tmp1_s32x4 = vsubq_s32( xq_Q14_s32x4, vshlq_n_s32( vdupq_n_s32( x_Q10[ i ] ), 4 ) ); | ||
780 | vst1q_s32( psSampleState[ 0 ].Diff_Q14, tmp1_s32x4 ); | ||
781 | sLF_AR_shp_Q14_s32x4 = vsubq_s32( tmp1_s32x4, n_AR_Q14_s32x4 ); | ||
782 | vst1q_s32( psSampleState[ 0 ].sLTP_shp_Q14, vsubq_s32( sLF_AR_shp_Q14_s32x4, n_LF_Q14_s32x4 ) ); | ||
783 | vst1q_s32( psSampleState[ 0 ].LF_AR_Q14, sLF_AR_shp_Q14_s32x4 ); | ||
784 | vst1q_s32( psSampleState[ 0 ].LPC_exc_Q14, LPC_exc_Q14_s32x4 ); | ||
785 | vst1q_s32( psSampleState[ 0 ].xq_Q14, xq_Q14_s32x4 ); | ||
786 | |||
787 | /* Quantized excitation */ | ||
788 | exc_Q14_s32x4 = vshlq_n_s32( tmp2_s32x4, 4 ); | ||
789 | exc_Q14_s32x4 = veorq_s32( exc_Q14_s32x4, sign_s32x4 ); | ||
790 | exc_Q14_s32x4 = vsubq_s32( exc_Q14_s32x4, sign_s32x4 ); | ||
791 | |||
792 | /* Add predictions */ | ||
793 | LPC_exc_Q14_s32x4 = vaddq_s32( exc_Q14_s32x4, vdupq_n_s32( LTP_pred_Q14 ) ); | ||
794 | xq_Q14_s32x4 = vaddq_s32( LPC_exc_Q14_s32x4, LPC_pred_Q14_s32x4 ); | ||
795 | |||
796 | /* Update states */ | ||
797 | tmp1_s32x4 = vsubq_s32( xq_Q14_s32x4, vshlq_n_s32( vdupq_n_s32( x_Q10[ i ] ), 4 ) ); | ||
798 | vst1q_s32( psSampleState[ 1 ].Diff_Q14, tmp1_s32x4 ); | ||
799 | sLF_AR_shp_Q14_s32x4 = vsubq_s32( tmp1_s32x4, n_AR_Q14_s32x4 ); | ||
800 | vst1q_s32( psSampleState[ 1 ].sLTP_shp_Q14, vsubq_s32( sLF_AR_shp_Q14_s32x4, n_LF_Q14_s32x4 ) ); | ||
801 | vst1q_s32( psSampleState[ 1 ].LF_AR_Q14, sLF_AR_shp_Q14_s32x4 ); | ||
802 | vst1q_s32( psSampleState[ 1 ].LPC_exc_Q14, LPC_exc_Q14_s32x4 ); | ||
803 | vst1q_s32( psSampleState[ 1 ].xq_Q14, xq_Q14_s32x4 ); | ||
804 | } | ||
805 | |||
806 | *smpl_buf_idx = *smpl_buf_idx ? ( *smpl_buf_idx - 1 ) : ( DECISION_DELAY - 1); | ||
807 | last_smple_idx = *smpl_buf_idx + decisionDelay + DECISION_DELAY; | ||
808 | if( last_smple_idx >= DECISION_DELAY ) last_smple_idx -= DECISION_DELAY; | ||
809 | if( last_smple_idx >= DECISION_DELAY ) last_smple_idx -= DECISION_DELAY; | ||
810 | |||
811 | /* Find winner */ | ||
812 | RDmin_Q10 = psSampleState[ 0 ].RD_Q10[ 0 ]; | ||
813 | Winner_ind = 0; | ||
814 | for( k = 1; k < nStatesDelayedDecision; k++ ) { | ||
815 | if( psSampleState[ 0 ].RD_Q10[ k ] < RDmin_Q10 ) { | ||
816 | RDmin_Q10 = psSampleState[ 0 ].RD_Q10[ k ]; | ||
817 | Winner_ind = k; | ||
818 | } | ||
819 | } | ||
820 | |||
821 | /* Increase RD values of expired states */ | ||
822 | { | ||
823 | uint32x4_t t_u32x4; | ||
824 | Winner_rand_state = psDelDec->RandState[ last_smple_idx ][ Winner_ind ]; | ||
825 | t_u32x4 = vceqq_s32( vld1q_s32( psDelDec->RandState[ last_smple_idx ] ), vdupq_n_s32( Winner_rand_state ) ); | ||
826 | t_u32x4 = vmvnq_u32( t_u32x4 ); | ||
827 | t_u32x4 = vshrq_n_u32( t_u32x4, 5 ); | ||
828 | tmp1_s32x4 = vld1q_s32( psSampleState[ 0 ].RD_Q10 ); | ||
829 | tmp2_s32x4 = vld1q_s32( psSampleState[ 1 ].RD_Q10 ); | ||
830 | tmp1_s32x4 = vaddq_s32( tmp1_s32x4, vreinterpretq_s32_u32( t_u32x4 ) ); | ||
831 | tmp2_s32x4 = vaddq_s32( tmp2_s32x4, vreinterpretq_s32_u32( t_u32x4 ) ); | ||
832 | vst1q_s32( psSampleState[ 0 ].RD_Q10, tmp1_s32x4 ); | ||
833 | vst1q_s32( psSampleState[ 1 ].RD_Q10, tmp2_s32x4 ); | ||
834 | |||
835 | /* Find worst in first set and best in second set */ | ||
836 | RDmax_Q10 = psSampleState[ 0 ].RD_Q10[ 0 ]; | ||
837 | RDmin_Q10 = psSampleState[ 1 ].RD_Q10[ 0 ]; | ||
838 | RDmax_ind = 0; | ||
839 | RDmin_ind = 0; | ||
840 | for( k = 1; k < nStatesDelayedDecision; k++ ) { | ||
841 | /* find worst in first set */ | ||
842 | if( psSampleState[ 0 ].RD_Q10[ k ] > RDmax_Q10 ) { | ||
843 | RDmax_Q10 = psSampleState[ 0 ].RD_Q10[ k ]; | ||
844 | RDmax_ind = k; | ||
845 | } | ||
846 | /* find best in second set */ | ||
847 | if( psSampleState[ 1 ].RD_Q10[ k ] < RDmin_Q10 ) { | ||
848 | RDmin_Q10 = psSampleState[ 1 ].RD_Q10[ k ]; | ||
849 | RDmin_ind = k; | ||
850 | } | ||
851 | } | ||
852 | } | ||
853 | |||
854 | /* Replace a state if best from second set outperforms worst in first set */ | ||
855 | if( RDmin_Q10 < RDmax_Q10 ) { | ||
856 | opus_int32 (*ptr)[NEON_MAX_DEL_DEC_STATES] = psDelDec->RandState; | ||
857 | const int numOthers = (int)( ( sizeof( NSQ_del_decs_struct ) - sizeof( ( (NSQ_del_decs_struct *)0 )->sLPC_Q14 ) ) | ||
858 | / ( NEON_MAX_DEL_DEC_STATES * sizeof( opus_int32 ) ) ); | ||
859 | /* Only ( predictLPCOrder - 1 ) of sLPC_Q14 buffer need to be updated, though the first several */ | ||
860 | /* useless sLPC_Q14[] will be different comparing with C when predictLPCOrder < NSQ_LPC_BUF_LENGTH. */ | ||
861 | /* Here just update constant ( NSQ_LPC_BUF_LENGTH - 1 ) for simplicity. */ | ||
862 | for( j = i + 1; j < i + NSQ_LPC_BUF_LENGTH; j++ ) { | ||
863 | psDelDec->sLPC_Q14[ j ][ RDmax_ind ] = psDelDec->sLPC_Q14[ j ][ RDmin_ind ]; | ||
864 | } | ||
865 | for( j = 0; j < numOthers; j++ ) { | ||
866 | ptr[ j ][ RDmax_ind ] = ptr[ j ][ RDmin_ind ]; | ||
867 | } | ||
868 | |||
869 | psSampleState[ 0 ].Q_Q10[ RDmax_ind ] = psSampleState[ 1 ].Q_Q10[ RDmin_ind ]; | ||
870 | psSampleState[ 0 ].RD_Q10[ RDmax_ind ] = psSampleState[ 1 ].RD_Q10[ RDmin_ind ]; | ||
871 | psSampleState[ 0 ].xq_Q14[ RDmax_ind ] = psSampleState[ 1 ].xq_Q14[ RDmin_ind ]; | ||
872 | psSampleState[ 0 ].LF_AR_Q14[ RDmax_ind ] = psSampleState[ 1 ].LF_AR_Q14[ RDmin_ind ]; | ||
873 | psSampleState[ 0 ].Diff_Q14[ RDmax_ind ] = psSampleState[ 1 ].Diff_Q14[ RDmin_ind ]; | ||
874 | psSampleState[ 0 ].sLTP_shp_Q14[ RDmax_ind ] = psSampleState[ 1 ].sLTP_shp_Q14[ RDmin_ind ]; | ||
875 | psSampleState[ 0 ].LPC_exc_Q14[ RDmax_ind ] = psSampleState[ 1 ].LPC_exc_Q14[ RDmin_ind ]; | ||
876 | } | ||
877 | |||
878 | /* Write samples from winner to output and long-term filter states */ | ||
879 | if( subfr > 0 || i >= decisionDelay ) { | ||
880 | pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDelDec->Q_Q10[ last_smple_idx ][ Winner_ind ], 10 ); | ||
881 | xq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( | ||
882 | silk_SMULWW( psDelDec->Xq_Q14[ last_smple_idx ][ Winner_ind ], delayedGain_Q10[ last_smple_idx ] ), 8 ) ); | ||
883 | NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay ] = psDelDec->Shape_Q14[ last_smple_idx ][ Winner_ind ]; | ||
884 | sLTP_Q15[ NSQ->sLTP_buf_idx - decisionDelay ] = psDelDec->Pred_Q15[ last_smple_idx ][ Winner_ind ]; | ||
885 | } | ||
886 | NSQ->sLTP_shp_buf_idx++; | ||
887 | NSQ->sLTP_buf_idx++; | ||
888 | |||
889 | /* Update states */ | ||
890 | vst1q_s32( psDelDec->LF_AR_Q14, vld1q_s32( psSampleState[ 0 ].LF_AR_Q14 ) ); | ||
891 | vst1q_s32( psDelDec->Diff_Q14, vld1q_s32( psSampleState[ 0 ].Diff_Q14 ) ); | ||
892 | vst1q_s32( psDelDec->sLPC_Q14[ NSQ_LPC_BUF_LENGTH + i ], vld1q_s32( psSampleState[ 0 ].xq_Q14 ) ); | ||
893 | vst1q_s32( psDelDec->Xq_Q14[ *smpl_buf_idx ], vld1q_s32( psSampleState[ 0 ].xq_Q14 ) ); | ||
894 | tmp1_s32x4 = vld1q_s32( psSampleState[ 0 ].Q_Q10 ); | ||
895 | vst1q_s32( psDelDec->Q_Q10[ *smpl_buf_idx ], tmp1_s32x4 ); | ||
896 | vst1q_s32( psDelDec->Pred_Q15[ *smpl_buf_idx ], vshlq_n_s32( vld1q_s32( psSampleState[ 0 ].LPC_exc_Q14 ), 1 ) ); | ||
897 | vst1q_s32( psDelDec->Shape_Q14[ *smpl_buf_idx ], vld1q_s32( psSampleState[ 0 ].sLTP_shp_Q14 ) ); | ||
898 | tmp1_s32x4 = vrshrq_n_s32( tmp1_s32x4, 10 ); | ||
899 | tmp1_s32x4 = vaddq_s32( vld1q_s32( psDelDec->Seed ), tmp1_s32x4 ); | ||
900 | vst1q_s32( psDelDec->Seed, tmp1_s32x4 ); | ||
901 | vst1q_s32( psDelDec->RandState[ *smpl_buf_idx ], tmp1_s32x4 ); | ||
902 | vst1q_s32( psDelDec->RD_Q10, vld1q_s32( psSampleState[ 0 ].RD_Q10 ) ); | ||
903 | delayedGain_Q10[ *smpl_buf_idx ] = Gain_Q10; | ||
904 | } | ||
905 | /* Update LPC states */ | ||
906 | silk_memcpy( psDelDec->sLPC_Q14[ 0 ], psDelDec->sLPC_Q14[ length ], NEON_MAX_DEL_DEC_STATES * NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) ); | ||
907 | |||
908 | RESTORE_STACK; | ||
909 | } | ||
910 | |||
911 | static OPUS_INLINE void silk_SMULWB_8_neon( | ||
912 | const opus_int16 *a, | ||
913 | const int32x2_t b, | ||
914 | opus_int32 *o | ||
915 | ) | ||
916 | { | ||
917 | const int16x8_t a_s16x8 = vld1q_s16( a ); | ||
918 | int32x4_t o0_s32x4, o1_s32x4; | ||
919 | |||
920 | o0_s32x4 = vshll_n_s16( vget_low_s16( a_s16x8 ), 15 ); | ||
921 | o1_s32x4 = vshll_n_s16( vget_high_s16( a_s16x8 ), 15 ); | ||
922 | o0_s32x4 = vqdmulhq_lane_s32( o0_s32x4, b, 0 ); | ||
923 | o1_s32x4 = vqdmulhq_lane_s32( o1_s32x4, b, 0 ); | ||
924 | vst1q_s32( o, o0_s32x4 ); | ||
925 | vst1q_s32( o + 4, o1_s32x4 ); | ||
926 | } | ||
927 | |||
928 | /* Only works when ( b >= -65536 ) && ( b < 65536 ). */ | ||
929 | static OPUS_INLINE void silk_SMULWW_small_b_4_neon( | ||
930 | opus_int32 *a, | ||
931 | const int32x2_t b_s32x2) | ||
932 | { | ||
933 | int32x4_t o_s32x4; | ||
934 | |||
935 | o_s32x4 = vld1q_s32( a ); | ||
936 | o_s32x4 = vqdmulhq_lane_s32( o_s32x4, b_s32x2, 0 ); | ||
937 | vst1q_s32( a, o_s32x4 ); | ||
938 | } | ||
939 | |||
940 | /* Only works when ( b >= -65536 ) && ( b < 65536 ). */ | ||
941 | static OPUS_INLINE void silk_SMULWW_small_b_8_neon( | ||
942 | opus_int32 *a, | ||
943 | const int32x2_t b_s32x2 | ||
944 | ) | ||
945 | { | ||
946 | int32x4_t o0_s32x4, o1_s32x4; | ||
947 | |||
948 | o0_s32x4 = vld1q_s32( a ); | ||
949 | o1_s32x4 = vld1q_s32( a + 4 ); | ||
950 | o0_s32x4 = vqdmulhq_lane_s32( o0_s32x4, b_s32x2, 0 ); | ||
951 | o1_s32x4 = vqdmulhq_lane_s32( o1_s32x4, b_s32x2, 0 ); | ||
952 | vst1q_s32( a, o0_s32x4 ); | ||
953 | vst1q_s32( a + 4, o1_s32x4 ); | ||
954 | } | ||
955 | |||
956 | static OPUS_INLINE void silk_SMULWW_4_neon( | ||
957 | opus_int32 *a, | ||
958 | const int32x2_t b_s32x2) | ||
959 | { | ||
960 | int32x4_t a_s32x4, o_s32x4; | ||
961 | |||
962 | a_s32x4 = vld1q_s32( a ); | ||
963 | o_s32x4 = vqdmulhq_lane_s32( a_s32x4, b_s32x2, 0 ); | ||
964 | o_s32x4 = vmlaq_lane_s32( o_s32x4, a_s32x4, b_s32x2, 1 ); | ||
965 | vst1q_s32( a, o_s32x4 ); | ||
966 | } | ||
967 | |||
968 | static OPUS_INLINE void silk_SMULWW_8_neon( | ||
969 | opus_int32 *a, | ||
970 | const int32x2_t b_s32x2 | ||
971 | ) | ||
972 | { | ||
973 | int32x4_t a0_s32x4, a1_s32x4, o0_s32x4, o1_s32x4; | ||
974 | |||
975 | a0_s32x4 = vld1q_s32( a ); | ||
976 | a1_s32x4 = vld1q_s32( a + 4 ); | ||
977 | o0_s32x4 = vqdmulhq_lane_s32( a0_s32x4, b_s32x2, 0 ); | ||
978 | o1_s32x4 = vqdmulhq_lane_s32( a1_s32x4, b_s32x2, 0 ); | ||
979 | o0_s32x4 = vmlaq_lane_s32( o0_s32x4, a0_s32x4, b_s32x2, 1 ); | ||
980 | o1_s32x4 = vmlaq_lane_s32( o1_s32x4, a1_s32x4, b_s32x2, 1 ); | ||
981 | vst1q_s32( a, o0_s32x4 ); | ||
982 | vst1q_s32( a + 4, o1_s32x4 ); | ||
983 | } | ||
984 | |||
985 | static OPUS_INLINE void silk_SMULWW_loop_neon( | ||
986 | const opus_int16 *a, | ||
987 | const opus_int32 b, | ||
988 | opus_int32 *o, | ||
989 | const opus_int loop_num | ||
990 | ) | ||
991 | { | ||
992 | opus_int i; | ||
993 | int32x2_t b_s32x2; | ||
994 | |||
995 | b_s32x2 = vdup_n_s32( b ); | ||
996 | for( i = 0; i < loop_num - 7; i += 8 ) { | ||
997 | silk_SMULWB_8_neon( a + i, b_s32x2, o + i ); | ||
998 | } | ||
999 | for( ; i < loop_num; i++ ) { | ||
1000 | o[ i ] = silk_SMULWW( a[ i ], b ); | ||
1001 | } | ||
1002 | } | ||
1003 | |||
1004 | static OPUS_INLINE void silk_nsq_del_dec_scale_states_neon( | ||
1005 | const silk_encoder_state *psEncC, /* I Encoder State */ | ||
1006 | silk_nsq_state *NSQ, /* I/O NSQ state */ | ||
1007 | NSQ_del_decs_struct psDelDec[], /* I/O Delayed decision states */ | ||
1008 | const opus_int16 x16[], /* I Input */ | ||
1009 | opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */ | ||
1010 | const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */ | ||
1011 | opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ | ||
1012 | opus_int subfr, /* I Subframe number */ | ||
1013 | const opus_int LTP_scale_Q14, /* I LTP state scaling */ | ||
1014 | const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ | ||
1015 | const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */ | ||
1016 | const opus_int signal_type, /* I Signal type */ | ||
1017 | const opus_int decisionDelay /* I Decision delay */ | ||
1018 | ) | ||
1019 | { | ||
1020 | opus_int i, lag; | ||
1021 | opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q26; | ||
1022 | |||
1023 | lag = pitchL[ subfr ]; | ||
1024 | inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 ); | ||
1025 | silk_assert( inv_gain_Q31 != 0 ); | ||
1026 | |||
1027 | /* Scale input */ | ||
1028 | inv_gain_Q26 = silk_RSHIFT_ROUND( inv_gain_Q31, 5 ); | ||
1029 | silk_SMULWW_loop_neon( x16, inv_gain_Q26, x_sc_Q10, psEncC->subfr_length ); | ||
1030 | |||
1031 | /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */ | ||
1032 | if( NSQ->rewhite_flag ) { | ||
1033 | if( subfr == 0 ) { | ||
1034 | /* Do LTP downscaling */ | ||
1035 | inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 ); | ||
1036 | } | ||
1037 | silk_SMULWW_loop_neon( sLTP + NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2, inv_gain_Q31, sLTP_Q15 + NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2, lag + LTP_ORDER / 2 ); | ||
1038 | } | ||
1039 | |||
1040 | /* Adjust for changing gain */ | ||
1041 | if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) { | ||
1042 | int32x2_t gain_adj_Q16_s32x2; | ||
1043 | gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 ); | ||
1044 | |||
1045 | /* Scale long-term shaping state */ | ||
1046 | if( ( gain_adj_Q16 >= -65536 ) && ( gain_adj_Q16 < 65536 ) ) { | ||
1047 | gain_adj_Q16_s32x2 = vdup_n_s32( silk_LSHIFT32( gain_adj_Q16, 15 ) ); | ||
1048 | for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx - 7; i += 8 ) { | ||
1049 | silk_SMULWW_small_b_8_neon( NSQ->sLTP_shp_Q14 + i, gain_adj_Q16_s32x2 ); | ||
1050 | } | ||
1051 | for( ; i < NSQ->sLTP_shp_buf_idx; i++ ) { | ||
1052 | NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] ); | ||
1053 | } | ||
1054 | |||
1055 | /* Scale long-term prediction state */ | ||
1056 | if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) { | ||
1057 | for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx - decisionDelay - 7; i += 8 ) { | ||
1058 | silk_SMULWW_small_b_8_neon( sLTP_Q15 + i, gain_adj_Q16_s32x2 ); | ||
1059 | } | ||
1060 | for( ; i < NSQ->sLTP_buf_idx - decisionDelay; i++ ) { | ||
1061 | sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] ); | ||
1062 | } | ||
1063 | } | ||
1064 | |||
1065 | /* Scale scalar states */ | ||
1066 | silk_SMULWW_small_b_4_neon( psDelDec->LF_AR_Q14, gain_adj_Q16_s32x2 ); | ||
1067 | silk_SMULWW_small_b_4_neon( psDelDec->Diff_Q14, gain_adj_Q16_s32x2 ); | ||
1068 | |||
1069 | /* Scale short-term prediction and shaping states */ | ||
1070 | for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) { | ||
1071 | silk_SMULWW_small_b_4_neon( psDelDec->sLPC_Q14[ i ], gain_adj_Q16_s32x2 ); | ||
1072 | } | ||
1073 | |||
1074 | for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) { | ||
1075 | silk_SMULWW_small_b_4_neon( psDelDec->sAR2_Q14[ i ], gain_adj_Q16_s32x2 ); | ||
1076 | } | ||
1077 | |||
1078 | for( i = 0; i < DECISION_DELAY; i++ ) { | ||
1079 | silk_SMULWW_small_b_4_neon( psDelDec->Pred_Q15[ i ], gain_adj_Q16_s32x2 ); | ||
1080 | silk_SMULWW_small_b_4_neon( psDelDec->Shape_Q14[ i ], gain_adj_Q16_s32x2 ); | ||
1081 | } | ||
1082 | } else { | ||
1083 | gain_adj_Q16_s32x2 = vdup_n_s32( silk_LSHIFT32( gain_adj_Q16 & 0x0000FFFF, 15 ) ); | ||
1084 | gain_adj_Q16_s32x2 = vset_lane_s32( gain_adj_Q16 >> 16, gain_adj_Q16_s32x2, 1 ); | ||
1085 | for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx - 7; i += 8 ) { | ||
1086 | silk_SMULWW_8_neon( NSQ->sLTP_shp_Q14 + i, gain_adj_Q16_s32x2 ); | ||
1087 | } | ||
1088 | for( ; i < NSQ->sLTP_shp_buf_idx; i++ ) { | ||
1089 | NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] ); | ||
1090 | } | ||
1091 | |||
1092 | /* Scale long-term prediction state */ | ||
1093 | if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) { | ||
1094 | for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx - decisionDelay - 7; i += 8 ) { | ||
1095 | silk_SMULWW_8_neon( sLTP_Q15 + i, gain_adj_Q16_s32x2 ); | ||
1096 | } | ||
1097 | for( ; i < NSQ->sLTP_buf_idx - decisionDelay; i++ ) { | ||
1098 | sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] ); | ||
1099 | } | ||
1100 | } | ||
1101 | |||
1102 | /* Scale scalar states */ | ||
1103 | silk_SMULWW_4_neon( psDelDec->LF_AR_Q14, gain_adj_Q16_s32x2 ); | ||
1104 | silk_SMULWW_4_neon( psDelDec->Diff_Q14, gain_adj_Q16_s32x2 ); | ||
1105 | |||
1106 | /* Scale short-term prediction and shaping states */ | ||
1107 | for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) { | ||
1108 | silk_SMULWW_4_neon( psDelDec->sLPC_Q14[ i ], gain_adj_Q16_s32x2 ); | ||
1109 | } | ||
1110 | |||
1111 | for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) { | ||
1112 | silk_SMULWW_4_neon( psDelDec->sAR2_Q14[ i ], gain_adj_Q16_s32x2 ); | ||
1113 | } | ||
1114 | |||
1115 | for( i = 0; i < DECISION_DELAY; i++ ) { | ||
1116 | silk_SMULWW_4_neon( psDelDec->Pred_Q15[ i ], gain_adj_Q16_s32x2 ); | ||
1117 | silk_SMULWW_4_neon( psDelDec->Shape_Q14[ i ], gain_adj_Q16_s32x2 ); | ||
1118 | } | ||
1119 | } | ||
1120 | |||
1121 | /* Save inverse gain */ | ||
1122 | NSQ->prev_gain_Q16 = Gains_Q16[ subfr ]; | ||
1123 | } | ||
1124 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/arm/NSQ_neon.c b/lib/rbcodec/codecs/libopus/silk/arm/NSQ_neon.c new file mode 100644 index 0000000000..9642529973 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/arm/NSQ_neon.c | |||
@@ -0,0 +1,112 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (C) 2014 Vidyo | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | #ifdef HAVE_CONFIG_H | ||
28 | #include "config.h" | ||
29 | #endif | ||
30 | |||
31 | #include <arm_neon.h> | ||
32 | #include "main.h" | ||
33 | #include "stack_alloc.h" | ||
34 | #include "NSQ.h" | ||
35 | #include "celt/cpu_support.h" | ||
36 | #include "celt/arm/armcpu.h" | ||
37 | |||
38 | opus_int32 silk_noise_shape_quantizer_short_prediction_neon(const opus_int32 *buf32, const opus_int32 *coef32, opus_int order) | ||
39 | { | ||
40 | int32x4_t coef0 = vld1q_s32(coef32); | ||
41 | int32x4_t coef1 = vld1q_s32(coef32 + 4); | ||
42 | int32x4_t coef2 = vld1q_s32(coef32 + 8); | ||
43 | int32x4_t coef3 = vld1q_s32(coef32 + 12); | ||
44 | |||
45 | int32x4_t a0 = vld1q_s32(buf32 - 15); | ||
46 | int32x4_t a1 = vld1q_s32(buf32 - 11); | ||
47 | int32x4_t a2 = vld1q_s32(buf32 - 7); | ||
48 | int32x4_t a3 = vld1q_s32(buf32 - 3); | ||
49 | |||
50 | int32x4_t b0 = vqdmulhq_s32(coef0, a0); | ||
51 | int32x4_t b1 = vqdmulhq_s32(coef1, a1); | ||
52 | int32x4_t b2 = vqdmulhq_s32(coef2, a2); | ||
53 | int32x4_t b3 = vqdmulhq_s32(coef3, a3); | ||
54 | |||
55 | int32x4_t c0 = vaddq_s32(b0, b1); | ||
56 | int32x4_t c1 = vaddq_s32(b2, b3); | ||
57 | |||
58 | int32x4_t d = vaddq_s32(c0, c1); | ||
59 | |||
60 | int64x2_t e = vpaddlq_s32(d); | ||
61 | |||
62 | int64x1_t f = vadd_s64(vget_low_s64(e), vget_high_s64(e)); | ||
63 | |||
64 | opus_int32 out = vget_lane_s32(vreinterpret_s32_s64(f), 0); | ||
65 | |||
66 | out += silk_RSHIFT( order, 1 ); | ||
67 | |||
68 | return out; | ||
69 | } | ||
70 | |||
71 | |||
72 | opus_int32 silk_NSQ_noise_shape_feedback_loop_neon(const opus_int32 *data0, opus_int32 *data1, const opus_int16 *coef, opus_int order) | ||
73 | { | ||
74 | opus_int32 out; | ||
75 | if (order == 8) | ||
76 | { | ||
77 | int32x4_t a00 = vdupq_n_s32(data0[0]); | ||
78 | int32x4_t a01 = vld1q_s32(data1); /* data1[0] ... [3] */ | ||
79 | |||
80 | int32x4_t a0 = vextq_s32 (a00, a01, 3); /* data0[0] data1[0] ...[2] */ | ||
81 | int32x4_t a1 = vld1q_s32(data1 + 3); /* data1[3] ... [6] */ | ||
82 | |||
83 | /*TODO: Convert these once in advance instead of once per sample, like | ||
84 | silk_noise_shape_quantizer_short_prediction_neon() does.*/ | ||
85 | int16x8_t coef16 = vld1q_s16(coef); | ||
86 | int32x4_t coef0 = vmovl_s16(vget_low_s16(coef16)); | ||
87 | int32x4_t coef1 = vmovl_s16(vget_high_s16(coef16)); | ||
88 | |||
89 | /*This is not bit-exact with the C version, since we do not drop the | ||
90 | lower 16 bits of each multiply, but wait until the end to truncate | ||
91 | precision. This is an encoder-specific calculation (and unlike | ||
92 | silk_noise_shape_quantizer_short_prediction_neon(), is not meant to | ||
93 | simulate what the decoder will do). We still could use vqdmulhq_s32() | ||
94 | like silk_noise_shape_quantizer_short_prediction_neon() and save | ||
95 | half the multiplies, but the speed difference is not large, since we | ||
96 | then need two extra adds.*/ | ||
97 | int64x2_t b0 = vmull_s32(vget_low_s32(a0), vget_low_s32(coef0)); | ||
98 | int64x2_t b1 = vmlal_s32(b0, vget_high_s32(a0), vget_high_s32(coef0)); | ||
99 | int64x2_t b2 = vmlal_s32(b1, vget_low_s32(a1), vget_low_s32(coef1)); | ||
100 | int64x2_t b3 = vmlal_s32(b2, vget_high_s32(a1), vget_high_s32(coef1)); | ||
101 | |||
102 | int64x1_t c = vadd_s64(vget_low_s64(b3), vget_high_s64(b3)); | ||
103 | int64x1_t cS = vrshr_n_s64(c, 15); | ||
104 | int32x2_t d = vreinterpret_s32_s64(cS); | ||
105 | |||
106 | out = vget_lane_s32(d, 0); | ||
107 | vst1q_s32(data1, a0); | ||
108 | vst1q_s32(data1 + 4, a1); | ||
109 | return out; | ||
110 | } | ||
111 | return silk_NSQ_noise_shape_feedback_loop_c(data0, data1, coef, order); | ||
112 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/arm/NSQ_neon.h b/lib/rbcodec/codecs/libopus/silk/arm/NSQ_neon.h new file mode 100644 index 0000000000..b31d9442d6 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/arm/NSQ_neon.h | |||
@@ -0,0 +1,114 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (C) 2014 Vidyo | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | #ifndef SILK_NSQ_NEON_H | ||
28 | #define SILK_NSQ_NEON_H | ||
29 | |||
30 | #include "cpu_support.h" | ||
31 | #include "SigProc_FIX.h" | ||
32 | |||
33 | #undef silk_short_prediction_create_arch_coef | ||
34 | /* For vectorized calc, reverse a_Q12 coefs, convert to 32-bit, and shift for vqdmulhq_s32. */ | ||
35 | static OPUS_INLINE void silk_short_prediction_create_arch_coef_neon(opus_int32 *out, const opus_int16 *in, opus_int order) | ||
36 | { | ||
37 | out[15] = silk_LSHIFT32(in[0], 15); | ||
38 | out[14] = silk_LSHIFT32(in[1], 15); | ||
39 | out[13] = silk_LSHIFT32(in[2], 15); | ||
40 | out[12] = silk_LSHIFT32(in[3], 15); | ||
41 | out[11] = silk_LSHIFT32(in[4], 15); | ||
42 | out[10] = silk_LSHIFT32(in[5], 15); | ||
43 | out[9] = silk_LSHIFT32(in[6], 15); | ||
44 | out[8] = silk_LSHIFT32(in[7], 15); | ||
45 | out[7] = silk_LSHIFT32(in[8], 15); | ||
46 | out[6] = silk_LSHIFT32(in[9], 15); | ||
47 | |||
48 | if (order == 16) | ||
49 | { | ||
50 | out[5] = silk_LSHIFT32(in[10], 15); | ||
51 | out[4] = silk_LSHIFT32(in[11], 15); | ||
52 | out[3] = silk_LSHIFT32(in[12], 15); | ||
53 | out[2] = silk_LSHIFT32(in[13], 15); | ||
54 | out[1] = silk_LSHIFT32(in[14], 15); | ||
55 | out[0] = silk_LSHIFT32(in[15], 15); | ||
56 | } | ||
57 | else | ||
58 | { | ||
59 | out[5] = 0; | ||
60 | out[4] = 0; | ||
61 | out[3] = 0; | ||
62 | out[2] = 0; | ||
63 | out[1] = 0; | ||
64 | out[0] = 0; | ||
65 | } | ||
66 | } | ||
67 | |||
68 | #if defined(OPUS_ARM_PRESUME_NEON_INTR) | ||
69 | |||
70 | #define silk_short_prediction_create_arch_coef(out, in, order) \ | ||
71 | (silk_short_prediction_create_arch_coef_neon(out, in, order)) | ||
72 | |||
73 | #elif defined(OPUS_HAVE_RTCD) && defined(OPUS_ARM_MAY_HAVE_NEON_INTR) | ||
74 | |||
75 | #define silk_short_prediction_create_arch_coef(out, in, order) \ | ||
76 | do { if (arch == OPUS_ARCH_ARM_NEON) { silk_short_prediction_create_arch_coef_neon(out, in, order); } } while (0) | ||
77 | |||
78 | #endif | ||
79 | |||
80 | opus_int32 silk_noise_shape_quantizer_short_prediction_neon(const opus_int32 *buf32, const opus_int32 *coef32, opus_int order); | ||
81 | |||
82 | opus_int32 silk_NSQ_noise_shape_feedback_loop_neon(const opus_int32 *data0, opus_int32 *data1, const opus_int16 *coef, opus_int order); | ||
83 | |||
84 | #if defined(OPUS_ARM_PRESUME_NEON_INTR) | ||
85 | #undef silk_noise_shape_quantizer_short_prediction | ||
86 | #define silk_noise_shape_quantizer_short_prediction(in, coef, coefRev, order, arch) \ | ||
87 | ((void)arch,silk_noise_shape_quantizer_short_prediction_neon(in, coefRev, order)) | ||
88 | |||
89 | #undef silk_NSQ_noise_shape_feedback_loop | ||
90 | #define silk_NSQ_noise_shape_feedback_loop(data0, data1, coef, order, arch) ((void)arch,silk_NSQ_noise_shape_feedback_loop_neon(data0, data1, coef, order)) | ||
91 | |||
92 | #elif defined(OPUS_HAVE_RTCD) && defined(OPUS_ARM_MAY_HAVE_NEON_INTR) | ||
93 | |||
94 | /* silk_noise_shape_quantizer_short_prediction implementations take different parameters based on arch | ||
95 | (coef vs. coefRev) so can't use the usual IMPL table implementation */ | ||
96 | #undef silk_noise_shape_quantizer_short_prediction | ||
97 | #define silk_noise_shape_quantizer_short_prediction(in, coef, coefRev, order, arch) \ | ||
98 | (arch == OPUS_ARCH_ARM_NEON ? \ | ||
99 | silk_noise_shape_quantizer_short_prediction_neon(in, coefRev, order) : \ | ||
100 | silk_noise_shape_quantizer_short_prediction_c(in, coef, order)) | ||
101 | |||
102 | extern opus_int32 | ||
103 | (*const SILK_NSQ_NOISE_SHAPE_FEEDBACK_LOOP_IMPL[OPUS_ARCHMASK+1])( | ||
104 | const opus_int32 *data0, opus_int32 *data1, const opus_int16 *coef, | ||
105 | opus_int order); | ||
106 | |||
107 | #undef silk_NSQ_noise_shape_feedback_loop | ||
108 | #define silk_NSQ_noise_shape_feedback_loop(data0, data1, coef, order, arch) \ | ||
109 | (SILK_NSQ_NOISE_SHAPE_FEEDBACK_LOOP_IMPL[(arch)&OPUS_ARCHMASK](data0, data1, \ | ||
110 | coef, order)) | ||
111 | |||
112 | #endif | ||
113 | |||
114 | #endif /* SILK_NSQ_NEON_H */ | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/arm/arm_silk_map.c b/lib/rbcodec/codecs/libopus/silk/arm/arm_silk_map.c new file mode 100644 index 0000000000..0b9bfec2ca --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/arm/arm_silk_map.c | |||
@@ -0,0 +1,123 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (C) 2014 Vidyo | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | #ifdef HAVE_CONFIG_H | ||
28 | # include "config.h" | ||
29 | #endif | ||
30 | |||
31 | #include "main_FIX.h" | ||
32 | #include "NSQ.h" | ||
33 | #include "SigProc_FIX.h" | ||
34 | |||
35 | #if defined(OPUS_HAVE_RTCD) | ||
36 | |||
37 | # if (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && \ | ||
38 | !defined(OPUS_ARM_PRESUME_NEON_INTR)) | ||
39 | |||
40 | void (*const SILK_BIQUAD_ALT_STRIDE2_IMPL[OPUS_ARCHMASK + 1])( | ||
41 | const opus_int16 *in, /* I input signal */ | ||
42 | const opus_int32 *B_Q28, /* I MA coefficients [3] */ | ||
43 | const opus_int32 *A_Q28, /* I AR coefficients [2] */ | ||
44 | opus_int32 *S, /* I/O State vector [4] */ | ||
45 | opus_int16 *out, /* O output signal */ | ||
46 | const opus_int32 len /* I signal length (must be even) */ | ||
47 | ) = { | ||
48 | silk_biquad_alt_stride2_c, /* ARMv4 */ | ||
49 | silk_biquad_alt_stride2_c, /* EDSP */ | ||
50 | silk_biquad_alt_stride2_c, /* Media */ | ||
51 | silk_biquad_alt_stride2_neon, /* Neon */ | ||
52 | }; | ||
53 | |||
54 | opus_int32 (*const SILK_LPC_INVERSE_PRED_GAIN_IMPL[OPUS_ARCHMASK + 1])( /* O Returns inverse prediction gain in energy domain, Q30 */ | ||
55 | const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */ | ||
56 | const opus_int order /* I Prediction order */ | ||
57 | ) = { | ||
58 | silk_LPC_inverse_pred_gain_c, /* ARMv4 */ | ||
59 | silk_LPC_inverse_pred_gain_c, /* EDSP */ | ||
60 | silk_LPC_inverse_pred_gain_c, /* Media */ | ||
61 | silk_LPC_inverse_pred_gain_neon, /* Neon */ | ||
62 | }; | ||
63 | |||
64 | void (*const SILK_NSQ_DEL_DEC_IMPL[OPUS_ARCHMASK + 1])( | ||
65 | const silk_encoder_state *psEncC, /* I Encoder State */ | ||
66 | silk_nsq_state *NSQ, /* I/O NSQ state */ | ||
67 | SideInfoIndices *psIndices, /* I/O Quantization Indices */ | ||
68 | const opus_int16 x16[], /* I Input */ | ||
69 | opus_int8 pulses[], /* O Quantized pulse signal */ | ||
70 | const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ | ||
71 | const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ | ||
72 | const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ | ||
73 | const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ | ||
74 | const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ | ||
75 | const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ | ||
76 | const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ | ||
77 | const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ | ||
78 | const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ | ||
79 | const opus_int LTP_scale_Q14 /* I LTP state scaling */ | ||
80 | ) = { | ||
81 | silk_NSQ_del_dec_c, /* ARMv4 */ | ||
82 | silk_NSQ_del_dec_c, /* EDSP */ | ||
83 | silk_NSQ_del_dec_c, /* Media */ | ||
84 | silk_NSQ_del_dec_neon, /* Neon */ | ||
85 | }; | ||
86 | |||
87 | /*There is no table for silk_noise_shape_quantizer_short_prediction because the | ||
88 | NEON version takes different parameters than the C version. | ||
89 | Instead RTCD is done via if statements at the call sites. | ||
90 | See NSQ_neon.h for details.*/ | ||
91 | |||
92 | opus_int32 | ||
93 | (*const SILK_NSQ_NOISE_SHAPE_FEEDBACK_LOOP_IMPL[OPUS_ARCHMASK+1])( | ||
94 | const opus_int32 *data0, opus_int32 *data1, const opus_int16 *coef, | ||
95 | opus_int order) = { | ||
96 | silk_NSQ_noise_shape_feedback_loop_c, /* ARMv4 */ | ||
97 | silk_NSQ_noise_shape_feedback_loop_c, /* EDSP */ | ||
98 | silk_NSQ_noise_shape_feedback_loop_c, /* Media */ | ||
99 | silk_NSQ_noise_shape_feedback_loop_neon, /* NEON */ | ||
100 | }; | ||
101 | |||
102 | # endif | ||
103 | |||
104 | # if defined(FIXED_POINT) && \ | ||
105 | defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR) | ||
106 | |||
107 | void (*const SILK_WARPED_AUTOCORRELATION_FIX_IMPL[OPUS_ARCHMASK + 1])( | ||
108 | opus_int32 *corr, /* O Result [order + 1] */ | ||
109 | opus_int *scale, /* O Scaling of the correlation vector */ | ||
110 | const opus_int16 *input, /* I Input data to correlate */ | ||
111 | const opus_int warping_Q16, /* I Warping coefficient */ | ||
112 | const opus_int length, /* I Length of input */ | ||
113 | const opus_int order /* I Correlation order (even) */ | ||
114 | ) = { | ||
115 | silk_warped_autocorrelation_FIX_c, /* ARMv4 */ | ||
116 | silk_warped_autocorrelation_FIX_c, /* EDSP */ | ||
117 | silk_warped_autocorrelation_FIX_c, /* Media */ | ||
118 | silk_warped_autocorrelation_FIX_neon, /* Neon */ | ||
119 | }; | ||
120 | |||
121 | # endif | ||
122 | |||
123 | #endif /* OPUS_HAVE_RTCD */ | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/arm/biquad_alt_arm.h b/lib/rbcodec/codecs/libopus/silk/arm/biquad_alt_arm.h new file mode 100644 index 0000000000..66ea9f43dd --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/arm/biquad_alt_arm.h | |||
@@ -0,0 +1,68 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2017 Google Inc. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifndef SILK_BIQUAD_ALT_ARM_H | ||
29 | # define SILK_BIQUAD_ALT_ARM_H | ||
30 | |||
31 | # include "celt/arm/armcpu.h" | ||
32 | |||
33 | # if defined(OPUS_ARM_MAY_HAVE_NEON_INTR) | ||
34 | void silk_biquad_alt_stride2_neon( | ||
35 | const opus_int16 *in, /* I input signal */ | ||
36 | const opus_int32 *B_Q28, /* I MA coefficients [3] */ | ||
37 | const opus_int32 *A_Q28, /* I AR coefficients [2] */ | ||
38 | opus_int32 *S, /* I/O State vector [4] */ | ||
39 | opus_int16 *out, /* O output signal */ | ||
40 | const opus_int32 len /* I signal length (must be even) */ | ||
41 | ); | ||
42 | |||
43 | # if !defined(OPUS_HAVE_RTCD) && defined(OPUS_ARM_PRESUME_NEON) | ||
44 | # define OVERRIDE_silk_biquad_alt_stride2 (1) | ||
45 | # define silk_biquad_alt_stride2(in, B_Q28, A_Q28, S, out, len, arch) ((void)(arch), PRESUME_NEON(silk_biquad_alt_stride2)(in, B_Q28, A_Q28, S, out, len)) | ||
46 | # endif | ||
47 | # endif | ||
48 | |||
49 | # if !defined(OVERRIDE_silk_biquad_alt_stride2) | ||
50 | /*Is run-time CPU detection enabled on this platform?*/ | ||
51 | # if defined(OPUS_HAVE_RTCD) && (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR)) | ||
52 | extern void (*const SILK_BIQUAD_ALT_STRIDE2_IMPL[OPUS_ARCHMASK+1])( | ||
53 | const opus_int16 *in, /* I input signal */ | ||
54 | const opus_int32 *B_Q28, /* I MA coefficients [3] */ | ||
55 | const opus_int32 *A_Q28, /* I AR coefficients [2] */ | ||
56 | opus_int32 *S, /* I/O State vector [4] */ | ||
57 | opus_int16 *out, /* O output signal */ | ||
58 | const opus_int32 len /* I signal length (must be even) */ | ||
59 | ); | ||
60 | # define OVERRIDE_silk_biquad_alt_stride2 (1) | ||
61 | # define silk_biquad_alt_stride2(in, B_Q28, A_Q28, S, out, len, arch) ((*SILK_BIQUAD_ALT_STRIDE2_IMPL[(arch)&OPUS_ARCHMASK])(in, B_Q28, A_Q28, S, out, len)) | ||
62 | # elif defined(OPUS_ARM_PRESUME_NEON_INTR) | ||
63 | # define OVERRIDE_silk_biquad_alt_stride2 (1) | ||
64 | # define silk_biquad_alt_stride2(in, B_Q28, A_Q28, S, out, len, arch) ((void)(arch), silk_biquad_alt_stride2_neon(in, B_Q28, A_Q28, S, out, len)) | ||
65 | # endif | ||
66 | # endif | ||
67 | |||
68 | #endif /* end SILK_BIQUAD_ALT_ARM_H */ | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/arm/biquad_alt_neon_intr.c b/lib/rbcodec/codecs/libopus/silk/arm/biquad_alt_neon_intr.c new file mode 100644 index 0000000000..9715733185 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/arm/biquad_alt_neon_intr.c | |||
@@ -0,0 +1,156 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2017 Google Inc. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include <arm_neon.h> | ||
33 | #ifdef OPUS_CHECK_ASM | ||
34 | # include <string.h> | ||
35 | # include "stack_alloc.h" | ||
36 | #endif | ||
37 | #include "SigProc_FIX.h" | ||
38 | |||
39 | static inline void silk_biquad_alt_stride2_kernel( const int32x4_t A_L_s32x4, const int32x4_t A_U_s32x4, const int32x4_t B_Q28_s32x4, const int32x2_t t_s32x2, const int32x4_t in_s32x4, int32x4_t *S_s32x4, int32x2_t *out32_Q14_s32x2 ) | ||
40 | { | ||
41 | int32x4_t t_s32x4, out32_Q14_s32x4; | ||
42 | |||
43 | *out32_Q14_s32x2 = vadd_s32( vget_low_s32( *S_s32x4 ), t_s32x2 ); /* silk_SMLAWB( S{0,1}, B_Q28[ 0 ], in{0,1} ) */ | ||
44 | *S_s32x4 = vcombine_s32( vget_high_s32( *S_s32x4 ), vdup_n_s32( 0 ) ); /* S{0,1} = S{2,3}; S{2,3} = 0; */ | ||
45 | *out32_Q14_s32x2 = vshl_n_s32( *out32_Q14_s32x2, 2 ); /* out32_Q14_{0,1} = silk_LSHIFT( silk_SMLAWB( S{0,1}, B_Q28[ 0 ], in{0,1} ), 2 ); */ | ||
46 | out32_Q14_s32x4 = vcombine_s32( *out32_Q14_s32x2, *out32_Q14_s32x2 ); /* out32_Q14_{0,1,0,1} */ | ||
47 | t_s32x4 = vqdmulhq_s32( out32_Q14_s32x4, A_L_s32x4 ); /* silk_SMULWB( out32_Q14_{0,1,0,1}, A{0,0,1,1}_L_Q28 ) */ | ||
48 | *S_s32x4 = vrsraq_n_s32( *S_s32x4, t_s32x4, 14 ); /* S{0,1} = S{2,3} + silk_RSHIFT_ROUND(); S{2,3} = silk_RSHIFT_ROUND(); */ | ||
49 | t_s32x4 = vqdmulhq_s32( out32_Q14_s32x4, A_U_s32x4 ); /* silk_SMULWB( out32_Q14_{0,1,0,1}, A{0,0,1,1}_U_Q28 ) */ | ||
50 | *S_s32x4 = vaddq_s32( *S_s32x4, t_s32x4 ); /* S0 = silk_SMLAWB( S{0,1,2,3}, out32_Q14_{0,1,0,1}, A{0,0,1,1}_U_Q28 ); */ | ||
51 | t_s32x4 = vqdmulhq_s32( in_s32x4, B_Q28_s32x4 ); /* silk_SMULWB( B_Q28[ {1,1,2,2} ], in{0,1,0,1} ) */ | ||
52 | *S_s32x4 = vaddq_s32( *S_s32x4, t_s32x4 ); /* S0 = silk_SMLAWB( S0, B_Q28[ {1,1,2,2} ], in{0,1,0,1} ); */ | ||
53 | } | ||
54 | |||
55 | void silk_biquad_alt_stride2_neon( | ||
56 | const opus_int16 *in, /* I input signal */ | ||
57 | const opus_int32 *B_Q28, /* I MA coefficients [3] */ | ||
58 | const opus_int32 *A_Q28, /* I AR coefficients [2] */ | ||
59 | opus_int32 *S, /* I/O State vector [4] */ | ||
60 | opus_int16 *out, /* O output signal */ | ||
61 | const opus_int32 len /* I signal length (must be even) */ | ||
62 | ) | ||
63 | { | ||
64 | /* DIRECT FORM II TRANSPOSED (uses 2 element state vector) */ | ||
65 | opus_int k = 0; | ||
66 | const int32x2_t offset_s32x2 = vdup_n_s32( (1<<14) - 1 ); | ||
67 | const int32x4_t offset_s32x4 = vcombine_s32( offset_s32x2, offset_s32x2 ); | ||
68 | int16x4_t in_s16x4 = vdup_n_s16( 0 ); | ||
69 | int16x4_t out_s16x4; | ||
70 | int32x2_t A_Q28_s32x2, A_L_s32x2, A_U_s32x2, B_Q28_s32x2, t_s32x2; | ||
71 | int32x4_t A_L_s32x4, A_U_s32x4, B_Q28_s32x4, S_s32x4, out32_Q14_s32x4; | ||
72 | int32x2x2_t t0_s32x2x2, t1_s32x2x2, t2_s32x2x2, S_s32x2x2; | ||
73 | |||
74 | #ifdef OPUS_CHECK_ASM | ||
75 | opus_int32 S_c[ 4 ]; | ||
76 | VARDECL( opus_int16, out_c ); | ||
77 | SAVE_STACK; | ||
78 | ALLOC( out_c, 2 * len, opus_int16 ); | ||
79 | |||
80 | silk_memcpy( &S_c, S, sizeof( S_c ) ); | ||
81 | silk_biquad_alt_stride2_c( in, B_Q28, A_Q28, S_c, out_c, len ); | ||
82 | #endif | ||
83 | |||
84 | /* Negate A_Q28 values and split in two parts */ | ||
85 | A_Q28_s32x2 = vld1_s32( A_Q28 ); | ||
86 | A_Q28_s32x2 = vneg_s32( A_Q28_s32x2 ); | ||
87 | A_L_s32x2 = vshl_n_s32( A_Q28_s32x2, 18 ); /* ( -A_Q28[] & 0x00003FFF ) << 18 */ | ||
88 | A_L_s32x2 = vreinterpret_s32_u32( vshr_n_u32( vreinterpret_u32_s32( A_L_s32x2 ), 3 ) ); /* ( -A_Q28[] & 0x00003FFF ) << 15 */ | ||
89 | A_U_s32x2 = vshr_n_s32( A_Q28_s32x2, 14 ); /* silk_RSHIFT( -A_Q28[], 14 ) */ | ||
90 | A_U_s32x2 = vshl_n_s32( A_U_s32x2, 16 ); /* silk_RSHIFT( -A_Q28[], 14 ) << 16 (Clip two leading bits to conform to C function.) */ | ||
91 | A_U_s32x2 = vshr_n_s32( A_U_s32x2, 1 ); /* silk_RSHIFT( -A_Q28[], 14 ) << 15 */ | ||
92 | |||
93 | B_Q28_s32x2 = vld1_s32( B_Q28 ); | ||
94 | t_s32x2 = vld1_s32( B_Q28 + 1 ); | ||
95 | t0_s32x2x2 = vzip_s32( A_L_s32x2, A_L_s32x2 ); | ||
96 | t1_s32x2x2 = vzip_s32( A_U_s32x2, A_U_s32x2 ); | ||
97 | t2_s32x2x2 = vzip_s32( t_s32x2, t_s32x2 ); | ||
98 | A_L_s32x4 = vcombine_s32( t0_s32x2x2.val[ 0 ], t0_s32x2x2.val[ 1 ] ); /* A{0,0,1,1}_L_Q28 */ | ||
99 | A_U_s32x4 = vcombine_s32( t1_s32x2x2.val[ 0 ], t1_s32x2x2.val[ 1 ] ); /* A{0,0,1,1}_U_Q28 */ | ||
100 | B_Q28_s32x4 = vcombine_s32( t2_s32x2x2.val[ 0 ], t2_s32x2x2.val[ 1 ] ); /* B_Q28[ {1,1,2,2} ] */ | ||
101 | S_s32x4 = vld1q_s32( S ); /* S0 = S[ 0 ]; S3 = S[ 3 ]; */ | ||
102 | S_s32x2x2 = vtrn_s32( vget_low_s32( S_s32x4 ), vget_high_s32( S_s32x4 ) ); /* S2 = S[ 1 ]; S1 = S[ 2 ]; */ | ||
103 | S_s32x4 = vcombine_s32( S_s32x2x2.val[ 0 ], S_s32x2x2.val[ 1 ] ); | ||
104 | |||
105 | for( ; k < len - 1; k += 2 ) { | ||
106 | int32x4_t in_s32x4[ 2 ], t_s32x4; | ||
107 | int32x2_t out32_Q14_s32x2[ 2 ]; | ||
108 | |||
109 | /* S[ 2 * i + 0 ], S[ 2 * i + 1 ], S[ 2 * i + 2 ], S[ 2 * i + 3 ]: Q12 */ | ||
110 | in_s16x4 = vld1_s16( &in[ 2 * k ] ); /* in{0,1,2,3} = in[ 2 * k + {0,1,2,3} ]; */ | ||
111 | in_s32x4[ 0 ] = vshll_n_s16( in_s16x4, 15 ); /* in{0,1,2,3} << 15 */ | ||
112 | t_s32x4 = vqdmulhq_lane_s32( in_s32x4[ 0 ], B_Q28_s32x2, 0 ); /* silk_SMULWB( B_Q28[ 0 ], in{0,1,2,3} ) */ | ||
113 | in_s32x4[ 1 ] = vcombine_s32( vget_high_s32( in_s32x4[ 0 ] ), vget_high_s32( in_s32x4[ 0 ] ) ); /* in{2,3,2,3} << 15 */ | ||
114 | in_s32x4[ 0 ] = vcombine_s32( vget_low_s32 ( in_s32x4[ 0 ] ), vget_low_s32 ( in_s32x4[ 0 ] ) ); /* in{0,1,0,1} << 15 */ | ||
115 | silk_biquad_alt_stride2_kernel( A_L_s32x4, A_U_s32x4, B_Q28_s32x4, vget_low_s32 ( t_s32x4 ), in_s32x4[ 0 ], &S_s32x4, &out32_Q14_s32x2[ 0 ] ); | ||
116 | silk_biquad_alt_stride2_kernel( A_L_s32x4, A_U_s32x4, B_Q28_s32x4, vget_high_s32( t_s32x4 ), in_s32x4[ 1 ], &S_s32x4, &out32_Q14_s32x2[ 1 ] ); | ||
117 | |||
118 | /* Scale back to Q0 and saturate */ | ||
119 | out32_Q14_s32x4 = vcombine_s32( out32_Q14_s32x2[ 0 ], out32_Q14_s32x2[ 1 ] ); /* out32_Q14_{0,1,2,3} */ | ||
120 | out32_Q14_s32x4 = vaddq_s32( out32_Q14_s32x4, offset_s32x4 ); /* out32_Q14_{0,1,2,3} + (1<<14) - 1 */ | ||
121 | out_s16x4 = vqshrn_n_s32( out32_Q14_s32x4, 14 ); /* (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14_{0,1,2,3} + (1<<14) - 1, 14 ) ) */ | ||
122 | vst1_s16( &out[ 2 * k ], out_s16x4 ); /* out[ 2 * k + {0,1,2,3} ] = (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14_{0,1,2,3} + (1<<14) - 1, 14 ) ); */ | ||
123 | } | ||
124 | |||
125 | /* Process leftover. */ | ||
126 | if( k < len ) { | ||
127 | int32x4_t in_s32x4; | ||
128 | int32x2_t out32_Q14_s32x2; | ||
129 | |||
130 | /* S[ 2 * i + 0 ], S[ 2 * i + 1 ]: Q12 */ | ||
131 | in_s16x4 = vld1_lane_s16( &in[ 2 * k + 0 ], in_s16x4, 0 ); /* in{0,1} = in[ 2 * k + {0,1} ]; */ | ||
132 | in_s16x4 = vld1_lane_s16( &in[ 2 * k + 1 ], in_s16x4, 1 ); /* in{0,1} = in[ 2 * k + {0,1} ]; */ | ||
133 | in_s32x4 = vshll_n_s16( in_s16x4, 15 ); /* in{0,1} << 15 */ | ||
134 | t_s32x2 = vqdmulh_lane_s32( vget_low_s32( in_s32x4 ), B_Q28_s32x2, 0 ); /* silk_SMULWB( B_Q28[ 0 ], in{0,1} ) */ | ||
135 | in_s32x4 = vcombine_s32( vget_low_s32( in_s32x4 ), vget_low_s32( in_s32x4 ) ); /* in{0,1,0,1} << 15 */ | ||
136 | silk_biquad_alt_stride2_kernel( A_L_s32x4, A_U_s32x4, B_Q28_s32x4, t_s32x2, in_s32x4, &S_s32x4, &out32_Q14_s32x2 ); | ||
137 | |||
138 | /* Scale back to Q0 and saturate */ | ||
139 | out32_Q14_s32x2 = vadd_s32( out32_Q14_s32x2, offset_s32x2 ); /* out32_Q14_{0,1} + (1<<14) - 1 */ | ||
140 | out32_Q14_s32x4 = vcombine_s32( out32_Q14_s32x2, out32_Q14_s32x2 ); /* out32_Q14_{0,1,0,1} + (1<<14) - 1 */ | ||
141 | out_s16x4 = vqshrn_n_s32( out32_Q14_s32x4, 14 ); /* (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14_{0,1,0,1} + (1<<14) - 1, 14 ) ) */ | ||
142 | vst1_lane_s16( &out[ 2 * k + 0 ], out_s16x4, 0 ); /* out[ 2 * k + 0 ] = (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14_0 + (1<<14) - 1, 14 ) ); */ | ||
143 | vst1_lane_s16( &out[ 2 * k + 1 ], out_s16x4, 1 ); /* out[ 2 * k + 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14_1 + (1<<14) - 1, 14 ) ); */ | ||
144 | } | ||
145 | |||
146 | vst1q_lane_s32( &S[ 0 ], S_s32x4, 0 ); /* S[ 0 ] = S0; */ | ||
147 | vst1q_lane_s32( &S[ 1 ], S_s32x4, 2 ); /* S[ 1 ] = S2; */ | ||
148 | vst1q_lane_s32( &S[ 2 ], S_s32x4, 1 ); /* S[ 2 ] = S1; */ | ||
149 | vst1q_lane_s32( &S[ 3 ], S_s32x4, 3 ); /* S[ 3 ] = S3; */ | ||
150 | |||
151 | #ifdef OPUS_CHECK_ASM | ||
152 | silk_assert( !memcmp( S_c, S, sizeof( S_c ) ) ); | ||
153 | silk_assert( !memcmp( out_c, out, 2 * len * sizeof( opus_int16 ) ) ); | ||
154 | RESTORE_STACK; | ||
155 | #endif | ||
156 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/arm/macros_arm64.h b/lib/rbcodec/codecs/libopus/silk/arm/macros_arm64.h new file mode 100644 index 0000000000..ed030413c5 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/arm/macros_arm64.h | |||
@@ -0,0 +1,39 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (C) 2015 Vidyo | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifndef SILK_MACROS_ARM64_H | ||
29 | #define SILK_MACROS_ARM64_H | ||
30 | |||
31 | #include <arm_neon.h> | ||
32 | |||
33 | #undef silk_ADD_SAT32 | ||
34 | #define silk_ADD_SAT32(a, b) (vqadds_s32((a), (b))) | ||
35 | |||
36 | #undef silk_SUB_SAT32 | ||
37 | #define silk_SUB_SAT32(a, b) (vqsubs_s32((a), (b))) | ||
38 | |||
39 | #endif /* SILK_MACROS_ARM64_H */ | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/arm/macros_armv4.h b/lib/rbcodec/codecs/libopus/silk/arm/macros_armv4.h index 3f30e97288..877eb18dd5 100644 --- a/lib/rbcodec/codecs/libopus/silk/arm/macros_armv4.h +++ b/lib/rbcodec/codecs/libopus/silk/arm/macros_armv4.h | |||
@@ -28,6 +28,11 @@ POSSIBILITY OF SUCH DAMAGE. | |||
28 | #ifndef SILK_MACROS_ARMv4_H | 28 | #ifndef SILK_MACROS_ARMv4_H |
29 | #define SILK_MACROS_ARMv4_H | 29 | #define SILK_MACROS_ARMv4_H |
30 | 30 | ||
31 | /* This macro only avoids the undefined behaviour from a left shift of | ||
32 | a negative value. It should only be used in macros that can't include | ||
33 | SigProc_FIX.h. In other cases, use silk_LSHIFT32(). */ | ||
34 | #define SAFE_SHL(a,b) ((opus_int32)((opus_uint32)(a) << (b))) | ||
35 | |||
31 | /* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */ | 36 | /* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */ |
32 | #undef silk_SMULWB | 37 | #undef silk_SMULWB |
33 | static OPUS_INLINE opus_int32 silk_SMULWB_armv4(opus_int32 a, opus_int16 b) | 38 | static OPUS_INLINE opus_int32 silk_SMULWB_armv4(opus_int32 a, opus_int16 b) |
@@ -38,7 +43,7 @@ static OPUS_INLINE opus_int32 silk_SMULWB_armv4(opus_int32 a, opus_int16 b) | |||
38 | "#silk_SMULWB\n\t" | 43 | "#silk_SMULWB\n\t" |
39 | "smull %0, %1, %2, %3\n\t" | 44 | "smull %0, %1, %2, %3\n\t" |
40 | : "=&r"(rd_lo), "=&r"(rd_hi) | 45 | : "=&r"(rd_lo), "=&r"(rd_hi) |
41 | : "%r"(a), "r"(b<<16) | 46 | : "%r"(a), "r"(SAFE_SHL(b,16)) |
42 | ); | 47 | ); |
43 | return rd_hi; | 48 | return rd_hi; |
44 | } | 49 | } |
@@ -80,7 +85,7 @@ static OPUS_INLINE opus_int32 silk_SMULWW_armv4(opus_int32 a, opus_int32 b) | |||
80 | : "=&r"(rd_lo), "=&r"(rd_hi) | 85 | : "=&r"(rd_lo), "=&r"(rd_hi) |
81 | : "%r"(a), "r"(b) | 86 | : "%r"(a), "r"(b) |
82 | ); | 87 | ); |
83 | return (rd_hi<<16)+(rd_lo>>16); | 88 | return SAFE_SHL(rd_hi,16)+(rd_lo>>16); |
84 | } | 89 | } |
85 | #define silk_SMULWW(a, b) (silk_SMULWW_armv4(a, b)) | 90 | #define silk_SMULWW(a, b) (silk_SMULWW_armv4(a, b)) |
86 | 91 | ||
@@ -96,8 +101,10 @@ static OPUS_INLINE opus_int32 silk_SMLAWW_armv4(opus_int32 a, opus_int32 b, | |||
96 | : "=&r"(rd_lo), "=&r"(rd_hi) | 101 | : "=&r"(rd_lo), "=&r"(rd_hi) |
97 | : "%r"(b), "r"(c) | 102 | : "%r"(b), "r"(c) |
98 | ); | 103 | ); |
99 | return a+(rd_hi<<16)+(rd_lo>>16); | 104 | return a+SAFE_SHL(rd_hi,16)+(rd_lo>>16); |
100 | } | 105 | } |
101 | #define silk_SMLAWW(a, b, c) (silk_SMLAWW_armv4(a, b, c)) | 106 | #define silk_SMLAWW(a, b, c) (silk_SMLAWW_armv4(a, b, c)) |
102 | 107 | ||
108 | #undef SAFE_SHL | ||
109 | |||
103 | #endif /* SILK_MACROS_ARMv4_H */ | 110 | #endif /* SILK_MACROS_ARMv4_H */ |
diff --git a/lib/rbcodec/codecs/libopus/silk/arm/macros_armv5e.h b/lib/rbcodec/codecs/libopus/silk/arm/macros_armv5e.h index aad4117e46..b14ec65ddb 100644 --- a/lib/rbcodec/codecs/libopus/silk/arm/macros_armv5e.h +++ b/lib/rbcodec/codecs/libopus/silk/arm/macros_armv5e.h | |||
@@ -29,6 +29,11 @@ POSSIBILITY OF SUCH DAMAGE. | |||
29 | #ifndef SILK_MACROS_ARMv5E_H | 29 | #ifndef SILK_MACROS_ARMv5E_H |
30 | #define SILK_MACROS_ARMv5E_H | 30 | #define SILK_MACROS_ARMv5E_H |
31 | 31 | ||
32 | /* This macro only avoids the undefined behaviour from a left shift of | ||
33 | a negative value. It should only be used in macros that can't include | ||
34 | SigProc_FIX.h. In other cases, use silk_LSHIFT32(). */ | ||
35 | #define SAFE_SHL(a,b) ((opus_int32)((opus_uint32)(a) << (b))) | ||
36 | |||
32 | /* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */ | 37 | /* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */ |
33 | #undef silk_SMULWB | 38 | #undef silk_SMULWB |
34 | static OPUS_INLINE opus_int32 silk_SMULWB_armv5e(opus_int32 a, opus_int16 b) | 39 | static OPUS_INLINE opus_int32 silk_SMULWB_armv5e(opus_int32 a, opus_int16 b) |
@@ -190,7 +195,7 @@ static OPUS_INLINE opus_int32 silk_CLZ16_armv5(opus_int16 in16) | |||
190 | "#silk_CLZ16\n\t" | 195 | "#silk_CLZ16\n\t" |
191 | "clz %0, %1;\n" | 196 | "clz %0, %1;\n" |
192 | : "=r"(res) | 197 | : "=r"(res) |
193 | : "r"(in16<<16|0x8000) | 198 | : "r"(SAFE_SHL(in16,16)|0x8000) |
194 | ); | 199 | ); |
195 | return res; | 200 | return res; |
196 | } | 201 | } |
@@ -210,4 +215,6 @@ static OPUS_INLINE opus_int32 silk_CLZ32_armv5(opus_int32 in32) | |||
210 | } | 215 | } |
211 | #define silk_CLZ32(in32) (silk_CLZ32_armv5(in32)) | 216 | #define silk_CLZ32(in32) (silk_CLZ32_armv5(in32)) |
212 | 217 | ||
218 | #undef SAFE_SHL | ||
219 | |||
213 | #endif /* SILK_MACROS_ARMv5E_H */ | 220 | #endif /* SILK_MACROS_ARMv5E_H */ |
diff --git a/lib/rbcodec/codecs/libopus/silk/biquad_alt.c b/lib/rbcodec/codecs/libopus/silk/biquad_alt.c new file mode 100644 index 0000000000..54566a43c0 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/biquad_alt.c | |||
@@ -0,0 +1,121 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | /* * | ||
29 | * silk_biquad_alt.c * | ||
30 | * * | ||
31 | * Second order ARMA filter * | ||
32 | * Can handle slowly varying filter coefficients * | ||
33 | * */ | ||
34 | |||
35 | #ifdef HAVE_CONFIG_H | ||
36 | #include "config.h" | ||
37 | #endif | ||
38 | |||
39 | #include "SigProc_FIX.h" | ||
40 | |||
41 | /* Second order ARMA filter, alternative implementation */ | ||
42 | void silk_biquad_alt_stride1( | ||
43 | const opus_int16 *in, /* I input signal */ | ||
44 | const opus_int32 *B_Q28, /* I MA coefficients [3] */ | ||
45 | const opus_int32 *A_Q28, /* I AR coefficients [2] */ | ||
46 | opus_int32 *S, /* I/O State vector [2] */ | ||
47 | opus_int16 *out, /* O output signal */ | ||
48 | const opus_int32 len /* I signal length (must be even) */ | ||
49 | ) | ||
50 | { | ||
51 | /* DIRECT FORM II TRANSPOSED (uses 2 element state vector) */ | ||
52 | opus_int k; | ||
53 | opus_int32 inval, A0_U_Q28, A0_L_Q28, A1_U_Q28, A1_L_Q28, out32_Q14; | ||
54 | |||
55 | /* Negate A_Q28 values and split in two parts */ | ||
56 | A0_L_Q28 = ( -A_Q28[ 0 ] ) & 0x00003FFF; /* lower part */ | ||
57 | A0_U_Q28 = silk_RSHIFT( -A_Q28[ 0 ], 14 ); /* upper part */ | ||
58 | A1_L_Q28 = ( -A_Q28[ 1 ] ) & 0x00003FFF; /* lower part */ | ||
59 | A1_U_Q28 = silk_RSHIFT( -A_Q28[ 1 ], 14 ); /* upper part */ | ||
60 | |||
61 | for( k = 0; k < len; k++ ) { | ||
62 | /* S[ 0 ], S[ 1 ]: Q12 */ | ||
63 | inval = in[ k ]; | ||
64 | out32_Q14 = silk_LSHIFT( silk_SMLAWB( S[ 0 ], B_Q28[ 0 ], inval ), 2 ); | ||
65 | |||
66 | S[ 0 ] = S[1] + silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14, A0_L_Q28 ), 14 ); | ||
67 | S[ 0 ] = silk_SMLAWB( S[ 0 ], out32_Q14, A0_U_Q28 ); | ||
68 | S[ 0 ] = silk_SMLAWB( S[ 0 ], B_Q28[ 1 ], inval); | ||
69 | |||
70 | S[ 1 ] = silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14, A1_L_Q28 ), 14 ); | ||
71 | S[ 1 ] = silk_SMLAWB( S[ 1 ], out32_Q14, A1_U_Q28 ); | ||
72 | S[ 1 ] = silk_SMLAWB( S[ 1 ], B_Q28[ 2 ], inval ); | ||
73 | |||
74 | /* Scale back to Q0 and saturate */ | ||
75 | out[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14 + (1<<14) - 1, 14 ) ); | ||
76 | } | ||
77 | } | ||
78 | |||
79 | void silk_biquad_alt_stride2_c( | ||
80 | const opus_int16 *in, /* I input signal */ | ||
81 | const opus_int32 *B_Q28, /* I MA coefficients [3] */ | ||
82 | const opus_int32 *A_Q28, /* I AR coefficients [2] */ | ||
83 | opus_int32 *S, /* I/O State vector [4] */ | ||
84 | opus_int16 *out, /* O output signal */ | ||
85 | const opus_int32 len /* I signal length (must be even) */ | ||
86 | ) | ||
87 | { | ||
88 | /* DIRECT FORM II TRANSPOSED (uses 2 element state vector) */ | ||
89 | opus_int k; | ||
90 | opus_int32 A0_U_Q28, A0_L_Q28, A1_U_Q28, A1_L_Q28, out32_Q14[ 2 ]; | ||
91 | |||
92 | /* Negate A_Q28 values and split in two parts */ | ||
93 | A0_L_Q28 = ( -A_Q28[ 0 ] ) & 0x00003FFF; /* lower part */ | ||
94 | A0_U_Q28 = silk_RSHIFT( -A_Q28[ 0 ], 14 ); /* upper part */ | ||
95 | A1_L_Q28 = ( -A_Q28[ 1 ] ) & 0x00003FFF; /* lower part */ | ||
96 | A1_U_Q28 = silk_RSHIFT( -A_Q28[ 1 ], 14 ); /* upper part */ | ||
97 | |||
98 | for( k = 0; k < len; k++ ) { | ||
99 | /* S[ 0 ], S[ 1 ], S[ 2 ], S[ 3 ]: Q12 */ | ||
100 | out32_Q14[ 0 ] = silk_LSHIFT( silk_SMLAWB( S[ 0 ], B_Q28[ 0 ], in[ 2 * k + 0 ] ), 2 ); | ||
101 | out32_Q14[ 1 ] = silk_LSHIFT( silk_SMLAWB( S[ 2 ], B_Q28[ 0 ], in[ 2 * k + 1 ] ), 2 ); | ||
102 | |||
103 | S[ 0 ] = S[ 1 ] + silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14[ 0 ], A0_L_Q28 ), 14 ); | ||
104 | S[ 2 ] = S[ 3 ] + silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14[ 1 ], A0_L_Q28 ), 14 ); | ||
105 | S[ 0 ] = silk_SMLAWB( S[ 0 ], out32_Q14[ 0 ], A0_U_Q28 ); | ||
106 | S[ 2 ] = silk_SMLAWB( S[ 2 ], out32_Q14[ 1 ], A0_U_Q28 ); | ||
107 | S[ 0 ] = silk_SMLAWB( S[ 0 ], B_Q28[ 1 ], in[ 2 * k + 0 ] ); | ||
108 | S[ 2 ] = silk_SMLAWB( S[ 2 ], B_Q28[ 1 ], in[ 2 * k + 1 ] ); | ||
109 | |||
110 | S[ 1 ] = silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14[ 0 ], A1_L_Q28 ), 14 ); | ||
111 | S[ 3 ] = silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14[ 1 ], A1_L_Q28 ), 14 ); | ||
112 | S[ 1 ] = silk_SMLAWB( S[ 1 ], out32_Q14[ 0 ], A1_U_Q28 ); | ||
113 | S[ 3 ] = silk_SMLAWB( S[ 3 ], out32_Q14[ 1 ], A1_U_Q28 ); | ||
114 | S[ 1 ] = silk_SMLAWB( S[ 1 ], B_Q28[ 2 ], in[ 2 * k + 0 ] ); | ||
115 | S[ 3 ] = silk_SMLAWB( S[ 3 ], B_Q28[ 2 ], in[ 2 * k + 1 ] ); | ||
116 | |||
117 | /* Scale back to Q0 and saturate */ | ||
118 | out[ 2 * k + 0 ] = (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14[ 0 ] + (1<<14) - 1, 14 ) ); | ||
119 | out[ 2 * k + 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14[ 1 ] + (1<<14) - 1, 14 ) ); | ||
120 | } | ||
121 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/bwexpander.c b/lib/rbcodec/codecs/libopus/silk/bwexpander.c index 2eb4456695..afa97907ec 100644 --- a/lib/rbcodec/codecs/libopus/silk/bwexpander.c +++ b/lib/rbcodec/codecs/libopus/silk/bwexpander.c | |||
@@ -45,7 +45,7 @@ void silk_bwexpander( | |||
45 | /* Bias in silk_SMULWB can lead to unstable filters */ | 45 | /* Bias in silk_SMULWB can lead to unstable filters */ |
46 | for( i = 0; i < d - 1; i++ ) { | 46 | for( i = 0; i < d - 1; i++ ) { |
47 | ar[ i ] = (opus_int16)silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, ar[ i ] ), 16 ); | 47 | ar[ i ] = (opus_int16)silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, ar[ i ] ), 16 ); |
48 | chirp_Q16 += silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, chirp_minus_one_Q16 ), 16 ); | 48 | chirp_Q16 += silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, chirp_minus_one_Q16 ), 16 ); |
49 | } | 49 | } |
50 | ar[ d - 1 ] = (opus_int16)silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, ar[ d - 1 ] ), 16 ); | 50 | ar[ d - 1 ] = (opus_int16)silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, ar[ d - 1 ] ), 16 ); |
51 | } | 51 | } |
diff --git a/lib/rbcodec/codecs/libopus/silk/check_control_input.c b/lib/rbcodec/codecs/libopus/silk/check_control_input.c new file mode 100644 index 0000000000..739fb01f1e --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/check_control_input.c | |||
@@ -0,0 +1,106 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main.h" | ||
33 | #include "control.h" | ||
34 | #include "errors.h" | ||
35 | |||
36 | /* Check encoder control struct */ | ||
37 | opus_int check_control_input( | ||
38 | silk_EncControlStruct *encControl /* I Control structure */ | ||
39 | ) | ||
40 | { | ||
41 | celt_assert( encControl != NULL ); | ||
42 | |||
43 | if( ( ( encControl->API_sampleRate != 8000 ) && | ||
44 | ( encControl->API_sampleRate != 12000 ) && | ||
45 | ( encControl->API_sampleRate != 16000 ) && | ||
46 | ( encControl->API_sampleRate != 24000 ) && | ||
47 | ( encControl->API_sampleRate != 32000 ) && | ||
48 | ( encControl->API_sampleRate != 44100 ) && | ||
49 | ( encControl->API_sampleRate != 48000 ) ) || | ||
50 | ( ( encControl->desiredInternalSampleRate != 8000 ) && | ||
51 | ( encControl->desiredInternalSampleRate != 12000 ) && | ||
52 | ( encControl->desiredInternalSampleRate != 16000 ) ) || | ||
53 | ( ( encControl->maxInternalSampleRate != 8000 ) && | ||
54 | ( encControl->maxInternalSampleRate != 12000 ) && | ||
55 | ( encControl->maxInternalSampleRate != 16000 ) ) || | ||
56 | ( ( encControl->minInternalSampleRate != 8000 ) && | ||
57 | ( encControl->minInternalSampleRate != 12000 ) && | ||
58 | ( encControl->minInternalSampleRate != 16000 ) ) || | ||
59 | ( encControl->minInternalSampleRate > encControl->desiredInternalSampleRate ) || | ||
60 | ( encControl->maxInternalSampleRate < encControl->desiredInternalSampleRate ) || | ||
61 | ( encControl->minInternalSampleRate > encControl->maxInternalSampleRate ) ) { | ||
62 | celt_assert( 0 ); | ||
63 | return SILK_ENC_FS_NOT_SUPPORTED; | ||
64 | } | ||
65 | if( encControl->payloadSize_ms != 10 && | ||
66 | encControl->payloadSize_ms != 20 && | ||
67 | encControl->payloadSize_ms != 40 && | ||
68 | encControl->payloadSize_ms != 60 ) { | ||
69 | celt_assert( 0 ); | ||
70 | return SILK_ENC_PACKET_SIZE_NOT_SUPPORTED; | ||
71 | } | ||
72 | if( encControl->packetLossPercentage < 0 || encControl->packetLossPercentage > 100 ) { | ||
73 | celt_assert( 0 ); | ||
74 | return SILK_ENC_INVALID_LOSS_RATE; | ||
75 | } | ||
76 | if( encControl->useDTX < 0 || encControl->useDTX > 1 ) { | ||
77 | celt_assert( 0 ); | ||
78 | return SILK_ENC_INVALID_DTX_SETTING; | ||
79 | } | ||
80 | if( encControl->useCBR < 0 || encControl->useCBR > 1 ) { | ||
81 | celt_assert( 0 ); | ||
82 | return SILK_ENC_INVALID_CBR_SETTING; | ||
83 | } | ||
84 | if( encControl->useInBandFEC < 0 || encControl->useInBandFEC > 1 ) { | ||
85 | celt_assert( 0 ); | ||
86 | return SILK_ENC_INVALID_INBAND_FEC_SETTING; | ||
87 | } | ||
88 | if( encControl->nChannelsAPI < 1 || encControl->nChannelsAPI > ENCODER_NUM_CHANNELS ) { | ||
89 | celt_assert( 0 ); | ||
90 | return SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR; | ||
91 | } | ||
92 | if( encControl->nChannelsInternal < 1 || encControl->nChannelsInternal > ENCODER_NUM_CHANNELS ) { | ||
93 | celt_assert( 0 ); | ||
94 | return SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR; | ||
95 | } | ||
96 | if( encControl->nChannelsInternal > encControl->nChannelsAPI ) { | ||
97 | celt_assert( 0 ); | ||
98 | return SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR; | ||
99 | } | ||
100 | if( encControl->complexity < 0 || encControl->complexity > 10 ) { | ||
101 | celt_assert( 0 ); | ||
102 | return SILK_ENC_INVALID_COMPLEXITY_SETTING; | ||
103 | } | ||
104 | |||
105 | return SILK_NO_ERROR; | ||
106 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/code_signs.c b/lib/rbcodec/codecs/libopus/silk/code_signs.c index 6ac25cb389..dfd1dca9a1 100644 --- a/lib/rbcodec/codecs/libopus/silk/code_signs.c +++ b/lib/rbcodec/codecs/libopus/silk/code_signs.c | |||
@@ -37,7 +37,6 @@ POSSIBILITY OF SUCH DAMAGE. | |||
37 | #define silk_enc_map(a) ( silk_RSHIFT( (a), 15 ) + 1 ) | 37 | #define silk_enc_map(a) ( silk_RSHIFT( (a), 15 ) + 1 ) |
38 | #define silk_dec_map(a) ( silk_LSHIFT( (a), 1 ) - 1 ) | 38 | #define silk_dec_map(a) ( silk_LSHIFT( (a), 1 ) - 1 ) |
39 | 39 | ||
40 | #if 0 | ||
41 | /* Encodes signs of excitation */ | 40 | /* Encodes signs of excitation */ |
42 | void silk_encode_signs( | 41 | void silk_encode_signs( |
43 | ec_enc *psRangeEnc, /* I/O Compressor data structure */ | 42 | ec_enc *psRangeEnc, /* I/O Compressor data structure */ |
@@ -71,7 +70,6 @@ void silk_encode_signs( | |||
71 | q_ptr += SHELL_CODEC_FRAME_LENGTH; | 70 | q_ptr += SHELL_CODEC_FRAME_LENGTH; |
72 | } | 71 | } |
73 | } | 72 | } |
74 | #endif | ||
75 | 73 | ||
76 | /* Decodes signs of excitation */ | 74 | /* Decodes signs of excitation */ |
77 | void silk_decode_signs( | 75 | void silk_decode_signs( |
diff --git a/lib/rbcodec/codecs/libopus/silk/control.h b/lib/rbcodec/codecs/libopus/silk/control.h index 747e5426a0..b76ec33cd6 100644 --- a/lib/rbcodec/codecs/libopus/silk/control.h +++ b/lib/rbcodec/codecs/libopus/silk/control.h | |||
@@ -77,6 +77,9 @@ typedef struct { | |||
77 | /* I: Flag to enable in-band Forward Error Correction (FEC); 0/1 */ | 77 | /* I: Flag to enable in-band Forward Error Correction (FEC); 0/1 */ |
78 | opus_int useInBandFEC; | 78 | opus_int useInBandFEC; |
79 | 79 | ||
80 | /* I: Flag to actually code in-band Forward Error Correction (FEC) in the current packet; 0/1 */ | ||
81 | opus_int LBRR_coded; | ||
82 | |||
80 | /* I: Flag to enable discontinuous transmission (DTX); 0/1 */ | 83 | /* I: Flag to enable discontinuous transmission (DTX); 0/1 */ |
81 | opus_int useDTX; | 84 | opus_int useDTX; |
82 | 85 | ||
@@ -110,6 +113,11 @@ typedef struct { | |||
110 | /* O: Tells the Opus encoder we're ready to switch */ | 113 | /* O: Tells the Opus encoder we're ready to switch */ |
111 | opus_int switchReady; | 114 | opus_int switchReady; |
112 | 115 | ||
116 | /* O: SILK Signal type */ | ||
117 | opus_int signalType; | ||
118 | |||
119 | /* O: SILK offset (dithering) */ | ||
120 | opus_int offset; | ||
113 | } silk_EncControlStruct; | 121 | } silk_EncControlStruct; |
114 | 122 | ||
115 | /**************************************************************************/ | 123 | /**************************************************************************/ |
diff --git a/lib/rbcodec/codecs/libopus/silk/control_SNR.c b/lib/rbcodec/codecs/libopus/silk/control_SNR.c new file mode 100644 index 0000000000..9a6db27543 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/control_SNR.c | |||
@@ -0,0 +1,113 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main.h" | ||
33 | #include "tuning_parameters.h" | ||
34 | |||
35 | /* These tables hold SNR values divided by 21 (so they fit in 8 bits) | ||
36 | for different target bitrates spaced at 400 bps interval. The first | ||
37 | 10 values are omitted (0-4 kb/s) because they're all zeros. | ||
38 | These tables were obtained by running different SNRs through the | ||
39 | encoder and measuring the active bitrate. */ | ||
40 | static const unsigned char silk_TargetRate_NB_21[117 - 10] = { | ||
41 | 0, 15, 39, 52, 61, 68, | ||
42 | 74, 79, 84, 88, 92, 95, 99,102,105,108,111,114,117,119,122,124, | ||
43 | 126,129,131,133,135,137,139,142,143,145,147,149,151,153,155,157, | ||
44 | 158,160,162,163,165,167,168,170,171,173,174,176,177,179,180,182, | ||
45 | 183,185,186,187,189,190,192,193,194,196,197,199,200,201,203,204, | ||
46 | 205,207,208,209,211,212,213,215,216,217,219,220,221,223,224,225, | ||
47 | 227,228,230,231,232,234,235,236,238,239,241,242,243,245,246,248, | ||
48 | 249,250,252,253,255 | ||
49 | }; | ||
50 | |||
51 | static const unsigned char silk_TargetRate_MB_21[165 - 10] = { | ||
52 | 0, 0, 28, 43, 52, 59, | ||
53 | 65, 70, 74, 78, 81, 85, 87, 90, 93, 95, 98,100,102,105,107,109, | ||
54 | 111,113,115,116,118,120,122,123,125,127,128,130,131,133,134,136, | ||
55 | 137,138,140,141,143,144,145,147,148,149,151,152,153,154,156,157, | ||
56 | 158,159,160,162,163,164,165,166,167,168,169,171,172,173,174,175, | ||
57 | 176,177,178,179,180,181,182,183,184,185,186,187,188,188,189,190, | ||
58 | 191,192,193,194,195,196,197,198,199,200,201,202,203,203,204,205, | ||
59 | 206,207,208,209,210,211,212,213,214,214,215,216,217,218,219,220, | ||
60 | 221,222,223,224,224,225,226,227,228,229,230,231,232,233,234,235, | ||
61 | 236,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250, | ||
62 | 251,252,253,254,255 | ||
63 | }; | ||
64 | |||
65 | static const unsigned char silk_TargetRate_WB_21[201 - 10] = { | ||
66 | 0, 0, 0, 8, 29, 41, | ||
67 | 49, 56, 62, 66, 70, 74, 77, 80, 83, 86, 88, 91, 93, 95, 97, 99, | ||
68 | 101,103,105,107,108,110,112,113,115,116,118,119,121,122,123,125, | ||
69 | 126,127,129,130,131,132,134,135,136,137,138,140,141,142,143,144, | ||
70 | 145,146,147,148,149,150,151,152,153,154,156,157,158,159,159,160, | ||
71 | 161,162,163,164,165,166,167,168,169,170,171,171,172,173,174,175, | ||
72 | 176,177,177,178,179,180,181,181,182,183,184,185,185,186,187,188, | ||
73 | 189,189,190,191,192,192,193,194,195,195,196,197,198,198,199,200, | ||
74 | 200,201,202,203,203,204,205,206,206,207,208,209,209,210,211,211, | ||
75 | 212,213,214,214,215,216,216,217,218,219,219,220,221,221,222,223, | ||
76 | 224,224,225,226,226,227,228,229,229,230,231,232,232,233,234,234, | ||
77 | 235,236,237,237,238,239,240,240,241,242,243,243,244,245,246,246, | ||
78 | 247,248,249,249,250,251,252,253,255 | ||
79 | }; | ||
80 | |||
81 | /* Control SNR of redidual quantizer */ | ||
82 | opus_int silk_control_SNR( | ||
83 | silk_encoder_state *psEncC, /* I/O Pointer to Silk encoder state */ | ||
84 | opus_int32 TargetRate_bps /* I Target max bitrate (bps) */ | ||
85 | ) | ||
86 | { | ||
87 | int id; | ||
88 | int bound; | ||
89 | const unsigned char *snr_table; | ||
90 | |||
91 | psEncC->TargetRate_bps = TargetRate_bps; | ||
92 | if( psEncC->nb_subfr == 2 ) { | ||
93 | TargetRate_bps -= 2000 + psEncC->fs_kHz/16; | ||
94 | } | ||
95 | if( psEncC->fs_kHz == 8 ) { | ||
96 | bound = sizeof(silk_TargetRate_NB_21); | ||
97 | snr_table = silk_TargetRate_NB_21; | ||
98 | } else if( psEncC->fs_kHz == 12 ) { | ||
99 | bound = sizeof(silk_TargetRate_MB_21); | ||
100 | snr_table = silk_TargetRate_MB_21; | ||
101 | } else { | ||
102 | bound = sizeof(silk_TargetRate_WB_21); | ||
103 | snr_table = silk_TargetRate_WB_21; | ||
104 | } | ||
105 | id = (TargetRate_bps+200)/400; | ||
106 | id = silk_min(id - 10, bound-1); | ||
107 | if( id <= 0 ) { | ||
108 | psEncC->SNR_dB_Q7 = 0; | ||
109 | } else { | ||
110 | psEncC->SNR_dB_Q7 = snr_table[id]*21; | ||
111 | } | ||
112 | return SILK_NO_ERROR; | ||
113 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/control_audio_bandwidth.c b/lib/rbcodec/codecs/libopus/silk/control_audio_bandwidth.c new file mode 100644 index 0000000000..f6d22d8395 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/control_audio_bandwidth.c | |||
@@ -0,0 +1,132 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main.h" | ||
33 | #include "tuning_parameters.h" | ||
34 | |||
35 | /* Control internal sampling rate */ | ||
36 | opus_int silk_control_audio_bandwidth( | ||
37 | silk_encoder_state *psEncC, /* I/O Pointer to Silk encoder state */ | ||
38 | silk_EncControlStruct *encControl /* I Control structure */ | ||
39 | ) | ||
40 | { | ||
41 | opus_int fs_kHz; | ||
42 | opus_int orig_kHz; | ||
43 | opus_int32 fs_Hz; | ||
44 | |||
45 | orig_kHz = psEncC->fs_kHz; | ||
46 | /* Handle a bandwidth-switching reset where we need to be aware what the last sampling rate was. */ | ||
47 | if( orig_kHz == 0 ) { | ||
48 | orig_kHz = psEncC->sLP.saved_fs_kHz; | ||
49 | } | ||
50 | fs_kHz = orig_kHz; | ||
51 | fs_Hz = silk_SMULBB( fs_kHz, 1000 ); | ||
52 | if( fs_Hz == 0 ) { | ||
53 | /* Encoder has just been initialized */ | ||
54 | fs_Hz = silk_min( psEncC->desiredInternal_fs_Hz, psEncC->API_fs_Hz ); | ||
55 | fs_kHz = silk_DIV32_16( fs_Hz, 1000 ); | ||
56 | } else if( fs_Hz > psEncC->API_fs_Hz || fs_Hz > psEncC->maxInternal_fs_Hz || fs_Hz < psEncC->minInternal_fs_Hz ) { | ||
57 | /* Make sure internal rate is not higher than external rate or maximum allowed, or lower than minimum allowed */ | ||
58 | fs_Hz = psEncC->API_fs_Hz; | ||
59 | fs_Hz = silk_min( fs_Hz, psEncC->maxInternal_fs_Hz ); | ||
60 | fs_Hz = silk_max( fs_Hz, psEncC->minInternal_fs_Hz ); | ||
61 | fs_kHz = silk_DIV32_16( fs_Hz, 1000 ); | ||
62 | } else { | ||
63 | /* State machine for the internal sampling rate switching */ | ||
64 | if( psEncC->sLP.transition_frame_no >= TRANSITION_FRAMES ) { | ||
65 | /* Stop transition phase */ | ||
66 | psEncC->sLP.mode = 0; | ||
67 | } | ||
68 | if( psEncC->allow_bandwidth_switch || encControl->opusCanSwitch ) { | ||
69 | /* Check if we should switch down */ | ||
70 | if( silk_SMULBB( orig_kHz, 1000 ) > psEncC->desiredInternal_fs_Hz ) | ||
71 | { | ||
72 | /* Switch down */ | ||
73 | if( psEncC->sLP.mode == 0 ) { | ||
74 | /* New transition */ | ||
75 | psEncC->sLP.transition_frame_no = TRANSITION_FRAMES; | ||
76 | |||
77 | /* Reset transition filter state */ | ||
78 | silk_memset( psEncC->sLP.In_LP_State, 0, sizeof( psEncC->sLP.In_LP_State ) ); | ||
79 | } | ||
80 | if( encControl->opusCanSwitch ) { | ||
81 | /* Stop transition phase */ | ||
82 | psEncC->sLP.mode = 0; | ||
83 | |||
84 | /* Switch to a lower sample frequency */ | ||
85 | fs_kHz = orig_kHz == 16 ? 12 : 8; | ||
86 | } else { | ||
87 | if( psEncC->sLP.transition_frame_no <= 0 ) { | ||
88 | encControl->switchReady = 1; | ||
89 | /* Make room for redundancy */ | ||
90 | encControl->maxBits -= encControl->maxBits * 5 / ( encControl->payloadSize_ms + 5 ); | ||
91 | } else { | ||
92 | /* Direction: down (at double speed) */ | ||
93 | psEncC->sLP.mode = -2; | ||
94 | } | ||
95 | } | ||
96 | } | ||
97 | else | ||
98 | /* Check if we should switch up */ | ||
99 | if( silk_SMULBB( orig_kHz, 1000 ) < psEncC->desiredInternal_fs_Hz ) | ||
100 | { | ||
101 | /* Switch up */ | ||
102 | if( encControl->opusCanSwitch ) { | ||
103 | /* Switch to a higher sample frequency */ | ||
104 | fs_kHz = orig_kHz == 8 ? 12 : 16; | ||
105 | |||
106 | /* New transition */ | ||
107 | psEncC->sLP.transition_frame_no = 0; | ||
108 | |||
109 | /* Reset transition filter state */ | ||
110 | silk_memset( psEncC->sLP.In_LP_State, 0, sizeof( psEncC->sLP.In_LP_State ) ); | ||
111 | |||
112 | /* Direction: up */ | ||
113 | psEncC->sLP.mode = 1; | ||
114 | } else { | ||
115 | if( psEncC->sLP.mode == 0 ) { | ||
116 | encControl->switchReady = 1; | ||
117 | /* Make room for redundancy */ | ||
118 | encControl->maxBits -= encControl->maxBits * 5 / ( encControl->payloadSize_ms + 5 ); | ||
119 | } else { | ||
120 | /* Direction: up */ | ||
121 | psEncC->sLP.mode = 1; | ||
122 | } | ||
123 | } | ||
124 | } else { | ||
125 | if (psEncC->sLP.mode<0) | ||
126 | psEncC->sLP.mode = 1; | ||
127 | } | ||
128 | } | ||
129 | } | ||
130 | |||
131 | return fs_kHz; | ||
132 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/control_codec.c b/lib/rbcodec/codecs/libopus/silk/control_codec.c new file mode 100644 index 0000000000..52aa8fded3 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/control_codec.c | |||
@@ -0,0 +1,423 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | #ifdef FIXED_POINT | ||
32 | #include "main_FIX.h" | ||
33 | #define silk_encoder_state_Fxx silk_encoder_state_FIX | ||
34 | #else | ||
35 | #include "main_FLP.h" | ||
36 | #define silk_encoder_state_Fxx silk_encoder_state_FLP | ||
37 | #endif | ||
38 | #include "stack_alloc.h" | ||
39 | #include "tuning_parameters.h" | ||
40 | #include "pitch_est_defines.h" | ||
41 | |||
42 | static opus_int silk_setup_resamplers( | ||
43 | silk_encoder_state_Fxx *psEnc, /* I/O */ | ||
44 | opus_int fs_kHz /* I */ | ||
45 | ); | ||
46 | |||
47 | static opus_int silk_setup_fs( | ||
48 | silk_encoder_state_Fxx *psEnc, /* I/O */ | ||
49 | opus_int fs_kHz, /* I */ | ||
50 | opus_int PacketSize_ms /* I */ | ||
51 | ); | ||
52 | |||
53 | static opus_int silk_setup_complexity( | ||
54 | silk_encoder_state *psEncC, /* I/O */ | ||
55 | opus_int Complexity /* I */ | ||
56 | ); | ||
57 | |||
58 | static OPUS_INLINE opus_int silk_setup_LBRR( | ||
59 | silk_encoder_state *psEncC, /* I/O */ | ||
60 | const silk_EncControlStruct *encControl /* I */ | ||
61 | ); | ||
62 | |||
63 | |||
64 | /* Control encoder */ | ||
65 | opus_int silk_control_encoder( | ||
66 | silk_encoder_state_Fxx *psEnc, /* I/O Pointer to Silk encoder state */ | ||
67 | silk_EncControlStruct *encControl, /* I Control structure */ | ||
68 | const opus_int allow_bw_switch, /* I Flag to allow switching audio bandwidth */ | ||
69 | const opus_int channelNb, /* I Channel number */ | ||
70 | const opus_int force_fs_kHz | ||
71 | ) | ||
72 | { | ||
73 | opus_int fs_kHz, ret = 0; | ||
74 | |||
75 | psEnc->sCmn.useDTX = encControl->useDTX; | ||
76 | psEnc->sCmn.useCBR = encControl->useCBR; | ||
77 | psEnc->sCmn.API_fs_Hz = encControl->API_sampleRate; | ||
78 | psEnc->sCmn.maxInternal_fs_Hz = encControl->maxInternalSampleRate; | ||
79 | psEnc->sCmn.minInternal_fs_Hz = encControl->minInternalSampleRate; | ||
80 | psEnc->sCmn.desiredInternal_fs_Hz = encControl->desiredInternalSampleRate; | ||
81 | psEnc->sCmn.useInBandFEC = encControl->useInBandFEC; | ||
82 | psEnc->sCmn.nChannelsAPI = encControl->nChannelsAPI; | ||
83 | psEnc->sCmn.nChannelsInternal = encControl->nChannelsInternal; | ||
84 | psEnc->sCmn.allow_bandwidth_switch = allow_bw_switch; | ||
85 | psEnc->sCmn.channelNb = channelNb; | ||
86 | |||
87 | if( psEnc->sCmn.controlled_since_last_payload != 0 && psEnc->sCmn.prefillFlag == 0 ) { | ||
88 | if( psEnc->sCmn.API_fs_Hz != psEnc->sCmn.prev_API_fs_Hz && psEnc->sCmn.fs_kHz > 0 ) { | ||
89 | /* Change in API sampling rate in the middle of encoding a packet */ | ||
90 | ret += silk_setup_resamplers( psEnc, psEnc->sCmn.fs_kHz ); | ||
91 | } | ||
92 | return ret; | ||
93 | } | ||
94 | |||
95 | /* Beyond this point we know that there are no previously coded frames in the payload buffer */ | ||
96 | |||
97 | /********************************************/ | ||
98 | /* Determine internal sampling rate */ | ||
99 | /********************************************/ | ||
100 | fs_kHz = silk_control_audio_bandwidth( &psEnc->sCmn, encControl ); | ||
101 | if( force_fs_kHz ) { | ||
102 | fs_kHz = force_fs_kHz; | ||
103 | } | ||
104 | /********************************************/ | ||
105 | /* Prepare resampler and buffered data */ | ||
106 | /********************************************/ | ||
107 | ret += silk_setup_resamplers( psEnc, fs_kHz ); | ||
108 | |||
109 | /********************************************/ | ||
110 | /* Set internal sampling frequency */ | ||
111 | /********************************************/ | ||
112 | ret += silk_setup_fs( psEnc, fs_kHz, encControl->payloadSize_ms ); | ||
113 | |||
114 | /********************************************/ | ||
115 | /* Set encoding complexity */ | ||
116 | /********************************************/ | ||
117 | ret += silk_setup_complexity( &psEnc->sCmn, encControl->complexity ); | ||
118 | |||
119 | /********************************************/ | ||
120 | /* Set packet loss rate measured by farend */ | ||
121 | /********************************************/ | ||
122 | psEnc->sCmn.PacketLoss_perc = encControl->packetLossPercentage; | ||
123 | |||
124 | /********************************************/ | ||
125 | /* Set LBRR usage */ | ||
126 | /********************************************/ | ||
127 | ret += silk_setup_LBRR( &psEnc->sCmn, encControl ); | ||
128 | |||
129 | psEnc->sCmn.controlled_since_last_payload = 1; | ||
130 | |||
131 | return ret; | ||
132 | } | ||
133 | |||
134 | static opus_int silk_setup_resamplers( | ||
135 | silk_encoder_state_Fxx *psEnc, /* I/O */ | ||
136 | opus_int fs_kHz /* I */ | ||
137 | ) | ||
138 | { | ||
139 | opus_int ret = SILK_NO_ERROR; | ||
140 | SAVE_STACK; | ||
141 | |||
142 | if( psEnc->sCmn.fs_kHz != fs_kHz || psEnc->sCmn.prev_API_fs_Hz != psEnc->sCmn.API_fs_Hz ) | ||
143 | { | ||
144 | if( psEnc->sCmn.fs_kHz == 0 ) { | ||
145 | /* Initialize the resampler for enc_API.c preparing resampling from API_fs_Hz to fs_kHz */ | ||
146 | ret += silk_resampler_init( &psEnc->sCmn.resampler_state, psEnc->sCmn.API_fs_Hz, fs_kHz * 1000, 1 ); | ||
147 | } else { | ||
148 | VARDECL( opus_int16, x_buf_API_fs_Hz ); | ||
149 | VARDECL( silk_resampler_state_struct, temp_resampler_state ); | ||
150 | #ifdef FIXED_POINT | ||
151 | opus_int16 *x_bufFIX = psEnc->x_buf; | ||
152 | #else | ||
153 | VARDECL( opus_int16, x_bufFIX ); | ||
154 | opus_int32 new_buf_samples; | ||
155 | #endif | ||
156 | opus_int32 api_buf_samples; | ||
157 | opus_int32 old_buf_samples; | ||
158 | opus_int32 buf_length_ms; | ||
159 | |||
160 | buf_length_ms = silk_LSHIFT( psEnc->sCmn.nb_subfr * 5, 1 ) + LA_SHAPE_MS; | ||
161 | old_buf_samples = buf_length_ms * psEnc->sCmn.fs_kHz; | ||
162 | |||
163 | #ifndef FIXED_POINT | ||
164 | new_buf_samples = buf_length_ms * fs_kHz; | ||
165 | ALLOC( x_bufFIX, silk_max( old_buf_samples, new_buf_samples ), | ||
166 | opus_int16 ); | ||
167 | silk_float2short_array( x_bufFIX, psEnc->x_buf, old_buf_samples ); | ||
168 | #endif | ||
169 | |||
170 | /* Initialize resampler for temporary resampling of x_buf data to API_fs_Hz */ | ||
171 | ALLOC( temp_resampler_state, 1, silk_resampler_state_struct ); | ||
172 | ret += silk_resampler_init( temp_resampler_state, silk_SMULBB( psEnc->sCmn.fs_kHz, 1000 ), psEnc->sCmn.API_fs_Hz, 0 ); | ||
173 | |||
174 | /* Calculate number of samples to temporarily upsample */ | ||
175 | api_buf_samples = buf_length_ms * silk_DIV32_16( psEnc->sCmn.API_fs_Hz, 1000 ); | ||
176 | |||
177 | /* Temporary resampling of x_buf data to API_fs_Hz */ | ||
178 | ALLOC( x_buf_API_fs_Hz, api_buf_samples, opus_int16 ); | ||
179 | ret += silk_resampler( temp_resampler_state, x_buf_API_fs_Hz, x_bufFIX, old_buf_samples ); | ||
180 | |||
181 | /* Initialize the resampler for enc_API.c preparing resampling from API_fs_Hz to fs_kHz */ | ||
182 | ret += silk_resampler_init( &psEnc->sCmn.resampler_state, psEnc->sCmn.API_fs_Hz, silk_SMULBB( fs_kHz, 1000 ), 1 ); | ||
183 | |||
184 | /* Correct resampler state by resampling buffered data from API_fs_Hz to fs_kHz */ | ||
185 | ret += silk_resampler( &psEnc->sCmn.resampler_state, x_bufFIX, x_buf_API_fs_Hz, api_buf_samples ); | ||
186 | |||
187 | #ifndef FIXED_POINT | ||
188 | silk_short2float_array( psEnc->x_buf, x_bufFIX, new_buf_samples); | ||
189 | #endif | ||
190 | } | ||
191 | } | ||
192 | |||
193 | psEnc->sCmn.prev_API_fs_Hz = psEnc->sCmn.API_fs_Hz; | ||
194 | |||
195 | RESTORE_STACK; | ||
196 | return ret; | ||
197 | } | ||
198 | |||
199 | static opus_int silk_setup_fs( | ||
200 | silk_encoder_state_Fxx *psEnc, /* I/O */ | ||
201 | opus_int fs_kHz, /* I */ | ||
202 | opus_int PacketSize_ms /* I */ | ||
203 | ) | ||
204 | { | ||
205 | opus_int ret = SILK_NO_ERROR; | ||
206 | |||
207 | /* Set packet size */ | ||
208 | if( PacketSize_ms != psEnc->sCmn.PacketSize_ms ) { | ||
209 | if( ( PacketSize_ms != 10 ) && | ||
210 | ( PacketSize_ms != 20 ) && | ||
211 | ( PacketSize_ms != 40 ) && | ||
212 | ( PacketSize_ms != 60 ) ) { | ||
213 | ret = SILK_ENC_PACKET_SIZE_NOT_SUPPORTED; | ||
214 | } | ||
215 | if( PacketSize_ms <= 10 ) { | ||
216 | psEnc->sCmn.nFramesPerPacket = 1; | ||
217 | psEnc->sCmn.nb_subfr = PacketSize_ms == 10 ? 2 : 1; | ||
218 | psEnc->sCmn.frame_length = silk_SMULBB( PacketSize_ms, fs_kHz ); | ||
219 | psEnc->sCmn.pitch_LPC_win_length = silk_SMULBB( FIND_PITCH_LPC_WIN_MS_2_SF, fs_kHz ); | ||
220 | if( psEnc->sCmn.fs_kHz == 8 ) { | ||
221 | psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_10_ms_NB_iCDF; | ||
222 | } else { | ||
223 | psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_10_ms_iCDF; | ||
224 | } | ||
225 | } else { | ||
226 | psEnc->sCmn.nFramesPerPacket = silk_DIV32_16( PacketSize_ms, MAX_FRAME_LENGTH_MS ); | ||
227 | psEnc->sCmn.nb_subfr = MAX_NB_SUBFR; | ||
228 | psEnc->sCmn.frame_length = silk_SMULBB( 20, fs_kHz ); | ||
229 | psEnc->sCmn.pitch_LPC_win_length = silk_SMULBB( FIND_PITCH_LPC_WIN_MS, fs_kHz ); | ||
230 | if( psEnc->sCmn.fs_kHz == 8 ) { | ||
231 | psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_NB_iCDF; | ||
232 | } else { | ||
233 | psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_iCDF; | ||
234 | } | ||
235 | } | ||
236 | psEnc->sCmn.PacketSize_ms = PacketSize_ms; | ||
237 | psEnc->sCmn.TargetRate_bps = 0; /* trigger new SNR computation */ | ||
238 | } | ||
239 | |||
240 | /* Set internal sampling frequency */ | ||
241 | celt_assert( fs_kHz == 8 || fs_kHz == 12 || fs_kHz == 16 ); | ||
242 | celt_assert( psEnc->sCmn.nb_subfr == 2 || psEnc->sCmn.nb_subfr == 4 ); | ||
243 | if( psEnc->sCmn.fs_kHz != fs_kHz ) { | ||
244 | /* reset part of the state */ | ||
245 | silk_memset( &psEnc->sShape, 0, sizeof( psEnc->sShape ) ); | ||
246 | silk_memset( &psEnc->sCmn.sNSQ, 0, sizeof( psEnc->sCmn.sNSQ ) ); | ||
247 | silk_memset( psEnc->sCmn.prev_NLSFq_Q15, 0, sizeof( psEnc->sCmn.prev_NLSFq_Q15 ) ); | ||
248 | silk_memset( &psEnc->sCmn.sLP.In_LP_State, 0, sizeof( psEnc->sCmn.sLP.In_LP_State ) ); | ||
249 | psEnc->sCmn.inputBufIx = 0; | ||
250 | psEnc->sCmn.nFramesEncoded = 0; | ||
251 | psEnc->sCmn.TargetRate_bps = 0; /* trigger new SNR computation */ | ||
252 | |||
253 | /* Initialize non-zero parameters */ | ||
254 | psEnc->sCmn.prevLag = 100; | ||
255 | psEnc->sCmn.first_frame_after_reset = 1; | ||
256 | psEnc->sShape.LastGainIndex = 10; | ||
257 | psEnc->sCmn.sNSQ.lagPrev = 100; | ||
258 | psEnc->sCmn.sNSQ.prev_gain_Q16 = 65536; | ||
259 | psEnc->sCmn.prevSignalType = TYPE_NO_VOICE_ACTIVITY; | ||
260 | |||
261 | psEnc->sCmn.fs_kHz = fs_kHz; | ||
262 | if( psEnc->sCmn.fs_kHz == 8 ) { | ||
263 | if( psEnc->sCmn.nb_subfr == MAX_NB_SUBFR ) { | ||
264 | psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_NB_iCDF; | ||
265 | } else { | ||
266 | psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_10_ms_NB_iCDF; | ||
267 | } | ||
268 | } else { | ||
269 | if( psEnc->sCmn.nb_subfr == MAX_NB_SUBFR ) { | ||
270 | psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_iCDF; | ||
271 | } else { | ||
272 | psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_10_ms_iCDF; | ||
273 | } | ||
274 | } | ||
275 | if( psEnc->sCmn.fs_kHz == 8 || psEnc->sCmn.fs_kHz == 12 ) { | ||
276 | psEnc->sCmn.predictLPCOrder = MIN_LPC_ORDER; | ||
277 | psEnc->sCmn.psNLSF_CB = &silk_NLSF_CB_NB_MB; | ||
278 | } else { | ||
279 | psEnc->sCmn.predictLPCOrder = MAX_LPC_ORDER; | ||
280 | psEnc->sCmn.psNLSF_CB = &silk_NLSF_CB_WB; | ||
281 | } | ||
282 | psEnc->sCmn.subfr_length = SUB_FRAME_LENGTH_MS * fs_kHz; | ||
283 | psEnc->sCmn.frame_length = silk_SMULBB( psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr ); | ||
284 | psEnc->sCmn.ltp_mem_length = silk_SMULBB( LTP_MEM_LENGTH_MS, fs_kHz ); | ||
285 | psEnc->sCmn.la_pitch = silk_SMULBB( LA_PITCH_MS, fs_kHz ); | ||
286 | psEnc->sCmn.max_pitch_lag = silk_SMULBB( 18, fs_kHz ); | ||
287 | if( psEnc->sCmn.nb_subfr == MAX_NB_SUBFR ) { | ||
288 | psEnc->sCmn.pitch_LPC_win_length = silk_SMULBB( FIND_PITCH_LPC_WIN_MS, fs_kHz ); | ||
289 | } else { | ||
290 | psEnc->sCmn.pitch_LPC_win_length = silk_SMULBB( FIND_PITCH_LPC_WIN_MS_2_SF, fs_kHz ); | ||
291 | } | ||
292 | if( psEnc->sCmn.fs_kHz == 16 ) { | ||
293 | psEnc->sCmn.pitch_lag_low_bits_iCDF = silk_uniform8_iCDF; | ||
294 | } else if( psEnc->sCmn.fs_kHz == 12 ) { | ||
295 | psEnc->sCmn.pitch_lag_low_bits_iCDF = silk_uniform6_iCDF; | ||
296 | } else { | ||
297 | psEnc->sCmn.pitch_lag_low_bits_iCDF = silk_uniform4_iCDF; | ||
298 | } | ||
299 | } | ||
300 | |||
301 | /* Check that settings are valid */ | ||
302 | celt_assert( ( psEnc->sCmn.subfr_length * psEnc->sCmn.nb_subfr ) == psEnc->sCmn.frame_length ); | ||
303 | |||
304 | return ret; | ||
305 | } | ||
306 | |||
307 | static opus_int silk_setup_complexity( | ||
308 | silk_encoder_state *psEncC, /* I/O */ | ||
309 | opus_int Complexity /* I */ | ||
310 | ) | ||
311 | { | ||
312 | opus_int ret = 0; | ||
313 | |||
314 | /* Set encoding complexity */ | ||
315 | celt_assert( Complexity >= 0 && Complexity <= 10 ); | ||
316 | if( Complexity < 1 ) { | ||
317 | psEncC->pitchEstimationComplexity = SILK_PE_MIN_COMPLEX; | ||
318 | psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.8, 16 ); | ||
319 | psEncC->pitchEstimationLPCOrder = 6; | ||
320 | psEncC->shapingLPCOrder = 12; | ||
321 | psEncC->la_shape = 3 * psEncC->fs_kHz; | ||
322 | psEncC->nStatesDelayedDecision = 1; | ||
323 | psEncC->useInterpolatedNLSFs = 0; | ||
324 | psEncC->NLSF_MSVQ_Survivors = 2; | ||
325 | psEncC->warping_Q16 = 0; | ||
326 | } else if( Complexity < 2 ) { | ||
327 | psEncC->pitchEstimationComplexity = SILK_PE_MID_COMPLEX; | ||
328 | psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.76, 16 ); | ||
329 | psEncC->pitchEstimationLPCOrder = 8; | ||
330 | psEncC->shapingLPCOrder = 14; | ||
331 | psEncC->la_shape = 5 * psEncC->fs_kHz; | ||
332 | psEncC->nStatesDelayedDecision = 1; | ||
333 | psEncC->useInterpolatedNLSFs = 0; | ||
334 | psEncC->NLSF_MSVQ_Survivors = 3; | ||
335 | psEncC->warping_Q16 = 0; | ||
336 | } else if( Complexity < 3 ) { | ||
337 | psEncC->pitchEstimationComplexity = SILK_PE_MIN_COMPLEX; | ||
338 | psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.8, 16 ); | ||
339 | psEncC->pitchEstimationLPCOrder = 6; | ||
340 | psEncC->shapingLPCOrder = 12; | ||
341 | psEncC->la_shape = 3 * psEncC->fs_kHz; | ||
342 | psEncC->nStatesDelayedDecision = 2; | ||
343 | psEncC->useInterpolatedNLSFs = 0; | ||
344 | psEncC->NLSF_MSVQ_Survivors = 2; | ||
345 | psEncC->warping_Q16 = 0; | ||
346 | } else if( Complexity < 4 ) { | ||
347 | psEncC->pitchEstimationComplexity = SILK_PE_MID_COMPLEX; | ||
348 | psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.76, 16 ); | ||
349 | psEncC->pitchEstimationLPCOrder = 8; | ||
350 | psEncC->shapingLPCOrder = 14; | ||
351 | psEncC->la_shape = 5 * psEncC->fs_kHz; | ||
352 | psEncC->nStatesDelayedDecision = 2; | ||
353 | psEncC->useInterpolatedNLSFs = 0; | ||
354 | psEncC->NLSF_MSVQ_Survivors = 4; | ||
355 | psEncC->warping_Q16 = 0; | ||
356 | } else if( Complexity < 6 ) { | ||
357 | psEncC->pitchEstimationComplexity = SILK_PE_MID_COMPLEX; | ||
358 | psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.74, 16 ); | ||
359 | psEncC->pitchEstimationLPCOrder = 10; | ||
360 | psEncC->shapingLPCOrder = 16; | ||
361 | psEncC->la_shape = 5 * psEncC->fs_kHz; | ||
362 | psEncC->nStatesDelayedDecision = 2; | ||
363 | psEncC->useInterpolatedNLSFs = 1; | ||
364 | psEncC->NLSF_MSVQ_Survivors = 6; | ||
365 | psEncC->warping_Q16 = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 ); | ||
366 | } else if( Complexity < 8 ) { | ||
367 | psEncC->pitchEstimationComplexity = SILK_PE_MID_COMPLEX; | ||
368 | psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.72, 16 ); | ||
369 | psEncC->pitchEstimationLPCOrder = 12; | ||
370 | psEncC->shapingLPCOrder = 20; | ||
371 | psEncC->la_shape = 5 * psEncC->fs_kHz; | ||
372 | psEncC->nStatesDelayedDecision = 3; | ||
373 | psEncC->useInterpolatedNLSFs = 1; | ||
374 | psEncC->NLSF_MSVQ_Survivors = 8; | ||
375 | psEncC->warping_Q16 = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 ); | ||
376 | } else { | ||
377 | psEncC->pitchEstimationComplexity = SILK_PE_MAX_COMPLEX; | ||
378 | psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.7, 16 ); | ||
379 | psEncC->pitchEstimationLPCOrder = 16; | ||
380 | psEncC->shapingLPCOrder = 24; | ||
381 | psEncC->la_shape = 5 * psEncC->fs_kHz; | ||
382 | psEncC->nStatesDelayedDecision = MAX_DEL_DEC_STATES; | ||
383 | psEncC->useInterpolatedNLSFs = 1; | ||
384 | psEncC->NLSF_MSVQ_Survivors = 16; | ||
385 | psEncC->warping_Q16 = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 ); | ||
386 | } | ||
387 | |||
388 | /* Do not allow higher pitch estimation LPC order than predict LPC order */ | ||
389 | psEncC->pitchEstimationLPCOrder = silk_min_int( psEncC->pitchEstimationLPCOrder, psEncC->predictLPCOrder ); | ||
390 | psEncC->shapeWinLength = SUB_FRAME_LENGTH_MS * psEncC->fs_kHz + 2 * psEncC->la_shape; | ||
391 | psEncC->Complexity = Complexity; | ||
392 | |||
393 | celt_assert( psEncC->pitchEstimationLPCOrder <= MAX_FIND_PITCH_LPC_ORDER ); | ||
394 | celt_assert( psEncC->shapingLPCOrder <= MAX_SHAPE_LPC_ORDER ); | ||
395 | celt_assert( psEncC->nStatesDelayedDecision <= MAX_DEL_DEC_STATES ); | ||
396 | celt_assert( psEncC->warping_Q16 <= 32767 ); | ||
397 | celt_assert( psEncC->la_shape <= LA_SHAPE_MAX ); | ||
398 | celt_assert( psEncC->shapeWinLength <= SHAPE_LPC_WIN_MAX ); | ||
399 | |||
400 | return ret; | ||
401 | } | ||
402 | |||
403 | static OPUS_INLINE opus_int silk_setup_LBRR( | ||
404 | silk_encoder_state *psEncC, /* I/O */ | ||
405 | const silk_EncControlStruct *encControl /* I */ | ||
406 | ) | ||
407 | { | ||
408 | opus_int LBRR_in_previous_packet, ret = SILK_NO_ERROR; | ||
409 | |||
410 | LBRR_in_previous_packet = psEncC->LBRR_enabled; | ||
411 | psEncC->LBRR_enabled = encControl->LBRR_coded; | ||
412 | if( psEncC->LBRR_enabled ) { | ||
413 | /* Set gain increase for coding LBRR excitation */ | ||
414 | if( LBRR_in_previous_packet == 0 ) { | ||
415 | /* Previous packet did not have LBRR, and was therefore coded at a higher bitrate */ | ||
416 | psEncC->LBRR_GainIncreases = 7; | ||
417 | } else { | ||
418 | psEncC->LBRR_GainIncreases = silk_max_int( 7 - silk_SMULWB( (opus_int32)psEncC->PacketLoss_perc, SILK_FIX_CONST( 0.4, 16 ) ), 2 ); | ||
419 | } | ||
420 | } | ||
421 | |||
422 | return ret; | ||
423 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/debug.c b/lib/rbcodec/codecs/libopus/silk/debug.c new file mode 100644 index 0000000000..9253faf71b --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/debug.c | |||
@@ -0,0 +1,170 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "debug.h" | ||
33 | #include "SigProc_FIX.h" | ||
34 | |||
35 | #if SILK_TIC_TOC | ||
36 | |||
37 | #ifdef _WIN32 | ||
38 | |||
39 | #if (defined(_WIN32) || defined(_WINCE)) | ||
40 | #include <windows.h> /* timer */ | ||
41 | #else /* Linux or Mac*/ | ||
42 | #include <sys/time.h> | ||
43 | #endif | ||
44 | |||
45 | unsigned long silk_GetHighResolutionTime(void) /* O time in usec*/ | ||
46 | { | ||
47 | /* Returns a time counter in microsec */ | ||
48 | /* the resolution is platform dependent */ | ||
49 | /* but is typically 1.62 us resolution */ | ||
50 | LARGE_INTEGER lpPerformanceCount; | ||
51 | LARGE_INTEGER lpFrequency; | ||
52 | QueryPerformanceCounter(&lpPerformanceCount); | ||
53 | QueryPerformanceFrequency(&lpFrequency); | ||
54 | return (unsigned long)((1000000*(lpPerformanceCount.QuadPart)) / lpFrequency.QuadPart); | ||
55 | } | ||
56 | #else /* Linux or Mac*/ | ||
57 | unsigned long GetHighResolutionTime(void) /* O time in usec*/ | ||
58 | { | ||
59 | struct timeval tv; | ||
60 | gettimeofday(&tv, 0); | ||
61 | return((tv.tv_sec*1000000)+(tv.tv_usec)); | ||
62 | } | ||
63 | #endif | ||
64 | |||
65 | int silk_Timer_nTimers = 0; | ||
66 | int silk_Timer_depth_ctr = 0; | ||
67 | char silk_Timer_tags[silk_NUM_TIMERS_MAX][silk_NUM_TIMERS_MAX_TAG_LEN]; | ||
68 | #ifdef WIN32 | ||
69 | LARGE_INTEGER silk_Timer_start[silk_NUM_TIMERS_MAX]; | ||
70 | #else | ||
71 | unsigned long silk_Timer_start[silk_NUM_TIMERS_MAX]; | ||
72 | #endif | ||
73 | unsigned int silk_Timer_cnt[silk_NUM_TIMERS_MAX]; | ||
74 | opus_int64 silk_Timer_min[silk_NUM_TIMERS_MAX]; | ||
75 | opus_int64 silk_Timer_sum[silk_NUM_TIMERS_MAX]; | ||
76 | opus_int64 silk_Timer_max[silk_NUM_TIMERS_MAX]; | ||
77 | opus_int64 silk_Timer_depth[silk_NUM_TIMERS_MAX]; | ||
78 | |||
79 | #ifdef WIN32 | ||
80 | void silk_TimerSave(char *file_name) | ||
81 | { | ||
82 | if( silk_Timer_nTimers > 0 ) | ||
83 | { | ||
84 | int k; | ||
85 | FILE *fp; | ||
86 | LARGE_INTEGER lpFrequency; | ||
87 | LARGE_INTEGER lpPerformanceCount1, lpPerformanceCount2; | ||
88 | int del = 0x7FFFFFFF; | ||
89 | double avg, sum_avg; | ||
90 | /* estimate overhead of calling performance counters */ | ||
91 | for( k = 0; k < 1000; k++ ) { | ||
92 | QueryPerformanceCounter(&lpPerformanceCount1); | ||
93 | QueryPerformanceCounter(&lpPerformanceCount2); | ||
94 | lpPerformanceCount2.QuadPart -= lpPerformanceCount1.QuadPart; | ||
95 | if( (int)lpPerformanceCount2.LowPart < del ) | ||
96 | del = lpPerformanceCount2.LowPart; | ||
97 | } | ||
98 | QueryPerformanceFrequency(&lpFrequency); | ||
99 | /* print results to file */ | ||
100 | sum_avg = 0.0f; | ||
101 | for( k = 0; k < silk_Timer_nTimers; k++ ) { | ||
102 | if (silk_Timer_depth[k] == 0) { | ||
103 | sum_avg += (1e6 * silk_Timer_sum[k] / silk_Timer_cnt[k] - del) / lpFrequency.QuadPart * silk_Timer_cnt[k]; | ||
104 | } | ||
105 | } | ||
106 | fp = fopen(file_name, "w"); | ||
107 | fprintf(fp, " min avg %% max count\n"); | ||
108 | for( k = 0; k < silk_Timer_nTimers; k++ ) { | ||
109 | if (silk_Timer_depth[k] == 0) { | ||
110 | fprintf(fp, "%-28s", silk_Timer_tags[k]); | ||
111 | } else if (silk_Timer_depth[k] == 1) { | ||
112 | fprintf(fp, " %-27s", silk_Timer_tags[k]); | ||
113 | } else if (silk_Timer_depth[k] == 2) { | ||
114 | fprintf(fp, " %-26s", silk_Timer_tags[k]); | ||
115 | } else if (silk_Timer_depth[k] == 3) { | ||
116 | fprintf(fp, " %-25s", silk_Timer_tags[k]); | ||
117 | } else { | ||
118 | fprintf(fp, " %-24s", silk_Timer_tags[k]); | ||
119 | } | ||
120 | avg = (1e6 * silk_Timer_sum[k] / silk_Timer_cnt[k] - del) / lpFrequency.QuadPart; | ||
121 | fprintf(fp, "%8.2f", (1e6 * (silk_max_64(silk_Timer_min[k] - del, 0))) / lpFrequency.QuadPart); | ||
122 | fprintf(fp, "%12.2f %6.2f", avg, 100.0 * avg / sum_avg * silk_Timer_cnt[k]); | ||
123 | fprintf(fp, "%12.2f", (1e6 * (silk_max_64(silk_Timer_max[k] - del, 0))) / lpFrequency.QuadPart); | ||
124 | fprintf(fp, "%10d\n", silk_Timer_cnt[k]); | ||
125 | } | ||
126 | fprintf(fp, " microseconds\n"); | ||
127 | fclose(fp); | ||
128 | } | ||
129 | } | ||
130 | #else | ||
131 | void silk_TimerSave(char *file_name) | ||
132 | { | ||
133 | if( silk_Timer_nTimers > 0 ) | ||
134 | { | ||
135 | int k; | ||
136 | FILE *fp; | ||
137 | /* print results to file */ | ||
138 | fp = fopen(file_name, "w"); | ||
139 | fprintf(fp, " min avg max count\n"); | ||
140 | for( k = 0; k < silk_Timer_nTimers; k++ ) | ||
141 | { | ||
142 | if (silk_Timer_depth[k] == 0) { | ||
143 | fprintf(fp, "%-28s", silk_Timer_tags[k]); | ||
144 | } else if (silk_Timer_depth[k] == 1) { | ||
145 | fprintf(fp, " %-27s", silk_Timer_tags[k]); | ||
146 | } else if (silk_Timer_depth[k] == 2) { | ||
147 | fprintf(fp, " %-26s", silk_Timer_tags[k]); | ||
148 | } else if (silk_Timer_depth[k] == 3) { | ||
149 | fprintf(fp, " %-25s", silk_Timer_tags[k]); | ||
150 | } else { | ||
151 | fprintf(fp, " %-24s", silk_Timer_tags[k]); | ||
152 | } | ||
153 | fprintf(fp, "%d ", silk_Timer_min[k]); | ||
154 | fprintf(fp, "%f ", (double)silk_Timer_sum[k] / (double)silk_Timer_cnt[k]); | ||
155 | fprintf(fp, "%d ", silk_Timer_max[k]); | ||
156 | fprintf(fp, "%10d\n", silk_Timer_cnt[k]); | ||
157 | } | ||
158 | fprintf(fp, " microseconds\n"); | ||
159 | fclose(fp); | ||
160 | } | ||
161 | } | ||
162 | #endif | ||
163 | |||
164 | #endif /* SILK_TIC_TOC */ | ||
165 | |||
166 | #if SILK_DEBUG | ||
167 | FILE *silk_debug_store_fp[ silk_NUM_STORES_MAX ]; | ||
168 | int silk_debug_store_count = 0; | ||
169 | #endif /* SILK_DEBUG */ | ||
170 | |||
diff --git a/lib/rbcodec/codecs/libopus/silk/debug.h b/lib/rbcodec/codecs/libopus/silk/debug.h new file mode 100644 index 0000000000..6f68c1ca0f --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/debug.h | |||
@@ -0,0 +1,266 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifndef SILK_DEBUG_H | ||
29 | #define SILK_DEBUG_H | ||
30 | |||
31 | #include "typedef.h" | ||
32 | #include <stdio.h> /* file writing */ | ||
33 | #include <string.h> /* strcpy, strcmp */ | ||
34 | |||
35 | #ifdef __cplusplus | ||
36 | extern "C" | ||
37 | { | ||
38 | #endif | ||
39 | |||
40 | unsigned long GetHighResolutionTime(void); /* O time in usec*/ | ||
41 | |||
42 | /* Set to 1 to enable DEBUG_STORE_DATA() macros for dumping | ||
43 | * intermediate signals from the codec. | ||
44 | */ | ||
45 | #define SILK_DEBUG 0 | ||
46 | |||
47 | /* Flag for using timers */ | ||
48 | #define SILK_TIC_TOC 0 | ||
49 | |||
50 | |||
51 | #if SILK_TIC_TOC | ||
52 | |||
53 | #if (defined(_WIN32) || defined(_WINCE)) | ||
54 | #include <windows.h> /* timer */ | ||
55 | #else /* Linux or Mac*/ | ||
56 | #include <sys/time.h> | ||
57 | #endif | ||
58 | |||
59 | /*********************************/ | ||
60 | /* timer functions for profiling */ | ||
61 | /*********************************/ | ||
62 | /* example: */ | ||
63 | /* */ | ||
64 | /* TIC(LPC) */ | ||
65 | /* do_LPC(in_vec, order, acoef); // do LPC analysis */ | ||
66 | /* TOC(LPC) */ | ||
67 | /* */ | ||
68 | /* and call the following just before exiting (from main) */ | ||
69 | /* */ | ||
70 | /* silk_TimerSave("silk_TimingData.txt"); */ | ||
71 | /* */ | ||
72 | /* results are now in silk_TimingData.txt */ | ||
73 | |||
74 | void silk_TimerSave(char *file_name); | ||
75 | |||
76 | /* max number of timers (in different locations) */ | ||
77 | #define silk_NUM_TIMERS_MAX 50 | ||
78 | /* max length of name tags in TIC(..), TOC(..) */ | ||
79 | #define silk_NUM_TIMERS_MAX_TAG_LEN 30 | ||
80 | |||
81 | extern int silk_Timer_nTimers; | ||
82 | extern int silk_Timer_depth_ctr; | ||
83 | extern char silk_Timer_tags[silk_NUM_TIMERS_MAX][silk_NUM_TIMERS_MAX_TAG_LEN]; | ||
84 | #ifdef _WIN32 | ||
85 | extern LARGE_INTEGER silk_Timer_start[silk_NUM_TIMERS_MAX]; | ||
86 | #else | ||
87 | extern unsigned long silk_Timer_start[silk_NUM_TIMERS_MAX]; | ||
88 | #endif | ||
89 | extern unsigned int silk_Timer_cnt[silk_NUM_TIMERS_MAX]; | ||
90 | extern opus_int64 silk_Timer_sum[silk_NUM_TIMERS_MAX]; | ||
91 | extern opus_int64 silk_Timer_max[silk_NUM_TIMERS_MAX]; | ||
92 | extern opus_int64 silk_Timer_min[silk_NUM_TIMERS_MAX]; | ||
93 | extern opus_int64 silk_Timer_depth[silk_NUM_TIMERS_MAX]; | ||
94 | |||
95 | /* WARNING: TIC()/TOC can measure only up to 0.1 seconds at a time */ | ||
96 | #ifdef _WIN32 | ||
97 | #define TIC(TAG_NAME) { \ | ||
98 | static int init = 0; \ | ||
99 | static int ID = -1; \ | ||
100 | if( init == 0 ) \ | ||
101 | { \ | ||
102 | int k; \ | ||
103 | init = 1; \ | ||
104 | for( k = 0; k < silk_Timer_nTimers; k++ ) { \ | ||
105 | if( strcmp(silk_Timer_tags[k], #TAG_NAME) == 0 ) { \ | ||
106 | ID = k; \ | ||
107 | break; \ | ||
108 | } \ | ||
109 | } \ | ||
110 | if (ID == -1) { \ | ||
111 | ID = silk_Timer_nTimers; \ | ||
112 | silk_Timer_nTimers++; \ | ||
113 | silk_Timer_depth[ID] = silk_Timer_depth_ctr; \ | ||
114 | strcpy(silk_Timer_tags[ID], #TAG_NAME); \ | ||
115 | silk_Timer_cnt[ID] = 0; \ | ||
116 | silk_Timer_sum[ID] = 0; \ | ||
117 | silk_Timer_min[ID] = 0xFFFFFFFF; \ | ||
118 | silk_Timer_max[ID] = 0; \ | ||
119 | } \ | ||
120 | } \ | ||
121 | silk_Timer_depth_ctr++; \ | ||
122 | QueryPerformanceCounter(&silk_Timer_start[ID]); \ | ||
123 | } | ||
124 | #else | ||
125 | #define TIC(TAG_NAME) { \ | ||
126 | static int init = 0; \ | ||
127 | static int ID = -1; \ | ||
128 | if( init == 0 ) \ | ||
129 | { \ | ||
130 | int k; \ | ||
131 | init = 1; \ | ||
132 | for( k = 0; k < silk_Timer_nTimers; k++ ) { \ | ||
133 | if( strcmp(silk_Timer_tags[k], #TAG_NAME) == 0 ) { \ | ||
134 | ID = k; \ | ||
135 | break; \ | ||
136 | } \ | ||
137 | } \ | ||
138 | if (ID == -1) { \ | ||
139 | ID = silk_Timer_nTimers; \ | ||
140 | silk_Timer_nTimers++; \ | ||
141 | silk_Timer_depth[ID] = silk_Timer_depth_ctr; \ | ||
142 | strcpy(silk_Timer_tags[ID], #TAG_NAME); \ | ||
143 | silk_Timer_cnt[ID] = 0; \ | ||
144 | silk_Timer_sum[ID] = 0; \ | ||
145 | silk_Timer_min[ID] = 0xFFFFFFFF; \ | ||
146 | silk_Timer_max[ID] = 0; \ | ||
147 | } \ | ||
148 | } \ | ||
149 | silk_Timer_depth_ctr++; \ | ||
150 | silk_Timer_start[ID] = GetHighResolutionTime(); \ | ||
151 | } | ||
152 | #endif | ||
153 | |||
154 | #ifdef _WIN32 | ||
155 | #define TOC(TAG_NAME) { \ | ||
156 | LARGE_INTEGER lpPerformanceCount; \ | ||
157 | static int init = 0; \ | ||
158 | static int ID = 0; \ | ||
159 | if( init == 0 ) \ | ||
160 | { \ | ||
161 | int k; \ | ||
162 | init = 1; \ | ||
163 | for( k = 0; k < silk_Timer_nTimers; k++ ) { \ | ||
164 | if( strcmp(silk_Timer_tags[k], #TAG_NAME) == 0 ) { \ | ||
165 | ID = k; \ | ||
166 | break; \ | ||
167 | } \ | ||
168 | } \ | ||
169 | } \ | ||
170 | QueryPerformanceCounter(&lpPerformanceCount); \ | ||
171 | lpPerformanceCount.QuadPart -= silk_Timer_start[ID].QuadPart; \ | ||
172 | if((lpPerformanceCount.QuadPart < 100000000) && \ | ||
173 | (lpPerformanceCount.QuadPart >= 0)) { \ | ||
174 | silk_Timer_cnt[ID]++; \ | ||
175 | silk_Timer_sum[ID] += lpPerformanceCount.QuadPart; \ | ||
176 | if( lpPerformanceCount.QuadPart > silk_Timer_max[ID] ) \ | ||
177 | silk_Timer_max[ID] = lpPerformanceCount.QuadPart; \ | ||
178 | if( lpPerformanceCount.QuadPart < silk_Timer_min[ID] ) \ | ||
179 | silk_Timer_min[ID] = lpPerformanceCount.QuadPart; \ | ||
180 | } \ | ||
181 | silk_Timer_depth_ctr--; \ | ||
182 | } | ||
183 | #else | ||
184 | #define TOC(TAG_NAME) { \ | ||
185 | unsigned long endTime; \ | ||
186 | static int init = 0; \ | ||
187 | static int ID = 0; \ | ||
188 | if( init == 0 ) \ | ||
189 | { \ | ||
190 | int k; \ | ||
191 | init = 1; \ | ||
192 | for( k = 0; k < silk_Timer_nTimers; k++ ) { \ | ||
193 | if( strcmp(silk_Timer_tags[k], #TAG_NAME) == 0 ) { \ | ||
194 | ID = k; \ | ||
195 | break; \ | ||
196 | } \ | ||
197 | } \ | ||
198 | } \ | ||
199 | endTime = GetHighResolutionTime(); \ | ||
200 | endTime -= silk_Timer_start[ID]; \ | ||
201 | if((endTime < 100000000) && \ | ||
202 | (endTime >= 0)) { \ | ||
203 | silk_Timer_cnt[ID]++; \ | ||
204 | silk_Timer_sum[ID] += endTime; \ | ||
205 | if( endTime > silk_Timer_max[ID] ) \ | ||
206 | silk_Timer_max[ID] = endTime; \ | ||
207 | if( endTime < silk_Timer_min[ID] ) \ | ||
208 | silk_Timer_min[ID] = endTime; \ | ||
209 | } \ | ||
210 | silk_Timer_depth_ctr--; \ | ||
211 | } | ||
212 | #endif | ||
213 | |||
214 | #else /* SILK_TIC_TOC */ | ||
215 | |||
216 | /* define macros as empty strings */ | ||
217 | #define TIC(TAG_NAME) | ||
218 | #define TOC(TAG_NAME) | ||
219 | #define silk_TimerSave(FILE_NAME) | ||
220 | |||
221 | #endif /* SILK_TIC_TOC */ | ||
222 | |||
223 | |||
224 | #if SILK_DEBUG | ||
225 | /************************************/ | ||
226 | /* write data to file for debugging */ | ||
227 | /************************************/ | ||
228 | /* Example: DEBUG_STORE_DATA(testfile.pcm, &RIN[0], 160*sizeof(opus_int16)); */ | ||
229 | |||
230 | #define silk_NUM_STORES_MAX 100 | ||
231 | extern FILE *silk_debug_store_fp[ silk_NUM_STORES_MAX ]; | ||
232 | extern int silk_debug_store_count; | ||
233 | |||
234 | /* Faster way of storing the data */ | ||
235 | #define DEBUG_STORE_DATA( FILE_NAME, DATA_PTR, N_BYTES ) { \ | ||
236 | static opus_int init = 0, cnt = 0; \ | ||
237 | static FILE **fp; \ | ||
238 | if (init == 0) { \ | ||
239 | init = 1; \ | ||
240 | cnt = silk_debug_store_count++; \ | ||
241 | silk_debug_store_fp[ cnt ] = fopen(#FILE_NAME, "wb"); \ | ||
242 | } \ | ||
243 | fwrite((DATA_PTR), (N_BYTES), 1, silk_debug_store_fp[ cnt ]); \ | ||
244 | } | ||
245 | |||
246 | /* Call this at the end of main() */ | ||
247 | #define SILK_DEBUG_STORE_CLOSE_FILES { \ | ||
248 | opus_int i; \ | ||
249 | for( i = 0; i < silk_debug_store_count; i++ ) { \ | ||
250 | fclose( silk_debug_store_fp[ i ] ); \ | ||
251 | } \ | ||
252 | } | ||
253 | |||
254 | #else /* SILK_DEBUG */ | ||
255 | |||
256 | /* define macros as empty strings */ | ||
257 | #define DEBUG_STORE_DATA(FILE_NAME, DATA_PTR, N_BYTES) | ||
258 | #define SILK_DEBUG_STORE_CLOSE_FILES | ||
259 | |||
260 | #endif /* SILK_DEBUG */ | ||
261 | |||
262 | #ifdef __cplusplus | ||
263 | } | ||
264 | #endif | ||
265 | |||
266 | #endif /* SILK_DEBUG_H */ | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/dec_API.c b/lib/rbcodec/codecs/libopus/silk/dec_API.c index 1087c6726a..7d5ca7fb9f 100644 --- a/lib/rbcodec/codecs/libopus/silk/dec_API.c +++ b/lib/rbcodec/codecs/libopus/silk/dec_API.c | |||
@@ -85,7 +85,8 @@ opus_int silk_Decode( /* O Returns error co | |||
85 | opus_int newPacketFlag, /* I Indicates first decoder call for this packet */ | 85 | opus_int newPacketFlag, /* I Indicates first decoder call for this packet */ |
86 | ec_dec *psRangeDec, /* I/O Compressor data structure */ | 86 | ec_dec *psRangeDec, /* I/O Compressor data structure */ |
87 | opus_int16 *samplesOut, /* O Decoded output speech vector */ | 87 | opus_int16 *samplesOut, /* O Decoded output speech vector */ |
88 | opus_int32 *nSamplesOut /* O Number of samples decoded */ | 88 | opus_int32 *nSamplesOut, /* O Number of samples decoded */ |
89 | int arch /* I Run-time architecture */ | ||
89 | ) | 90 | ) |
90 | { | 91 | { |
91 | opus_int i, n, decode_only_middle = 0, ret = SILK_NO_ERROR; | 92 | opus_int i, n, decode_only_middle = 0, ret = SILK_NO_ERROR; |
@@ -103,7 +104,7 @@ opus_int silk_Decode( /* O Returns error co | |||
103 | int delay_stack_alloc; | 104 | int delay_stack_alloc; |
104 | SAVE_STACK; | 105 | SAVE_STACK; |
105 | 106 | ||
106 | silk_assert( decControl->nChannelsInternal == 1 || decControl->nChannelsInternal == 2 ); | 107 | celt_assert( decControl->nChannelsInternal == 1 || decControl->nChannelsInternal == 2 ); |
107 | 108 | ||
108 | /**********************************/ | 109 | /**********************************/ |
109 | /* Test if first frame in payload */ | 110 | /* Test if first frame in payload */ |
@@ -142,13 +143,13 @@ opus_int silk_Decode( /* O Returns error co | |||
142 | channel_state[ n ].nFramesPerPacket = 3; | 143 | channel_state[ n ].nFramesPerPacket = 3; |
143 | channel_state[ n ].nb_subfr = 4; | 144 | channel_state[ n ].nb_subfr = 4; |
144 | } else { | 145 | } else { |
145 | silk_assert( 0 ); | 146 | celt_assert( 0 ); |
146 | RESTORE_STACK; | 147 | RESTORE_STACK; |
147 | return SILK_DEC_INVALID_FRAME_SIZE; | 148 | return SILK_DEC_INVALID_FRAME_SIZE; |
148 | } | 149 | } |
149 | fs_kHz_dec = ( decControl->internalSampleRate >> 10 ) + 1; | 150 | fs_kHz_dec = ( decControl->internalSampleRate >> 10 ) + 1; |
150 | if( fs_kHz_dec != 8 && fs_kHz_dec != 12 && fs_kHz_dec != 16 ) { | 151 | if( fs_kHz_dec != 8 && fs_kHz_dec != 12 && fs_kHz_dec != 16 ) { |
151 | silk_assert( 0 ); | 152 | celt_assert( 0 ); |
152 | RESTORE_STACK; | 153 | RESTORE_STACK; |
153 | return SILK_DEC_INVALID_SAMPLING_FREQUENCY; | 154 | return SILK_DEC_INVALID_SAMPLING_FREQUENCY; |
154 | } | 155 | } |
@@ -296,7 +297,7 @@ opus_int silk_Decode( /* O Returns error co | |||
296 | } else { | 297 | } else { |
297 | condCoding = CODE_CONDITIONALLY; | 298 | condCoding = CODE_CONDITIONALLY; |
298 | } | 299 | } |
299 | ret += silk_decode_frame( &channel_state[ n ], psRangeDec, &samplesOut1_tmp[ n ][ 2 ], &nSamplesOutDec, lostFlag, condCoding); | 300 | ret += silk_decode_frame( &channel_state[ n ], psRangeDec, &samplesOut1_tmp[ n ][ 2 ], &nSamplesOutDec, lostFlag, condCoding, arch); |
300 | } else { | 301 | } else { |
301 | silk_memset( &samplesOut1_tmp[ n ][ 2 ], 0, nSamplesOutDec * sizeof( opus_int16 ) ); | 302 | silk_memset( &samplesOut1_tmp[ n ][ 2 ], 0, nSamplesOutDec * sizeof( opus_int16 ) ); |
302 | } | 303 | } |
diff --git a/lib/rbcodec/codecs/libopus/silk/decode_core.c b/lib/rbcodec/codecs/libopus/silk/decode_core.c index af68b75da9..1c352a6522 100644 --- a/lib/rbcodec/codecs/libopus/silk/decode_core.c +++ b/lib/rbcodec/codecs/libopus/silk/decode_core.c | |||
@@ -39,7 +39,8 @@ void silk_decode_core( | |||
39 | silk_decoder_state *psDec, /* I/O Decoder state */ | 39 | silk_decoder_state *psDec, /* I/O Decoder state */ |
40 | silk_decoder_control *psDecCtrl, /* I Decoder control */ | 40 | silk_decoder_control *psDecCtrl, /* I Decoder control */ |
41 | opus_int16 xq[], /* O Decoded speech */ | 41 | opus_int16 xq[], /* O Decoded speech */ |
42 | const opus_int16 pulses[ MAX_FRAME_LENGTH ] /* I Pulse signal */ | 42 | const opus_int16 pulses[ MAX_FRAME_LENGTH ], /* I Pulse signal */ |
43 | int arch /* I Run-time architecture */ | ||
43 | ) | 44 | ) |
44 | { | 45 | { |
45 | opus_int i, k, lag = 0, start_idx, sLTP_buf_idx, NLSF_interpolation_flag, signalType; | 46 | opus_int i, k, lag = 0, start_idx, sLTP_buf_idx, NLSF_interpolation_flag, signalType; |
@@ -140,14 +141,14 @@ void silk_decode_core( | |||
140 | if( k == 0 || ( k == 2 && NLSF_interpolation_flag ) ) { | 141 | if( k == 0 || ( k == 2 && NLSF_interpolation_flag ) ) { |
141 | /* Rewhiten with new A coefs */ | 142 | /* Rewhiten with new A coefs */ |
142 | start_idx = psDec->ltp_mem_length - lag - psDec->LPC_order - LTP_ORDER / 2; | 143 | start_idx = psDec->ltp_mem_length - lag - psDec->LPC_order - LTP_ORDER / 2; |
143 | silk_assert( start_idx > 0 ); | 144 | celt_assert( start_idx > 0 ); |
144 | 145 | ||
145 | if( k == 2 ) { | 146 | if( k == 2 ) { |
146 | silk_memcpy( &psDec->outBuf[ psDec->ltp_mem_length ], xq, 2 * psDec->subfr_length * sizeof( opus_int16 ) ); | 147 | silk_memcpy( &psDec->outBuf[ psDec->ltp_mem_length ], xq, 2 * psDec->subfr_length * sizeof( opus_int16 ) ); |
147 | } | 148 | } |
148 | 149 | ||
149 | silk_LPC_analysis_filter( &sLTP[ start_idx ], &psDec->outBuf[ start_idx + k * psDec->subfr_length ], | 150 | silk_LPC_analysis_filter( &sLTP[ start_idx ], &psDec->outBuf[ start_idx + k * psDec->subfr_length ], |
150 | A_Q12, psDec->ltp_mem_length - start_idx, psDec->LPC_order ); | 151 | A_Q12, psDec->ltp_mem_length - start_idx, psDec->LPC_order, arch ); |
151 | 152 | ||
152 | /* After rewhitening the LTP state is unscaled */ | 153 | /* After rewhitening the LTP state is unscaled */ |
153 | if( k == 0 ) { | 154 | if( k == 0 ) { |
@@ -195,7 +196,7 @@ void silk_decode_core( | |||
195 | 196 | ||
196 | for( i = 0; i < psDec->subfr_length; i++ ) { | 197 | for( i = 0; i < psDec->subfr_length; i++ ) { |
197 | /* Short-term prediction */ | 198 | /* Short-term prediction */ |
198 | silk_assert( psDec->LPC_order == 10 || psDec->LPC_order == 16 ); | 199 | celt_assert( psDec->LPC_order == 10 || psDec->LPC_order == 16 ); |
199 | /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ | 200 | /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ |
200 | LPC_pred_Q10 = silk_RSHIFT( psDec->LPC_order, 1 ); | 201 | LPC_pred_Q10 = silk_RSHIFT( psDec->LPC_order, 1 ); |
201 | LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 1 ], A_Q12_tmp[ 0 ] ); | 202 | LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 1 ], A_Q12_tmp[ 0 ] ); |
@@ -218,14 +219,12 @@ void silk_decode_core( | |||
218 | } | 219 | } |
219 | 220 | ||
220 | /* Add prediction to LPC excitation */ | 221 | /* Add prediction to LPC excitation */ |
221 | sLPC_Q14[ MAX_LPC_ORDER + i ] = silk_ADD_LSHIFT32( pres_Q14[ i ], LPC_pred_Q10, 4 ); | 222 | sLPC_Q14[ MAX_LPC_ORDER + i ] = silk_ADD_SAT32( pres_Q14[ i ], silk_LSHIFT_SAT32( LPC_pred_Q10, 4 ) ); |
222 | 223 | ||
223 | /* Scale with gain */ | 224 | /* Scale with gain */ |
224 | pxq[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( sLPC_Q14[ MAX_LPC_ORDER + i ], Gain_Q10 ), 8 ) ); | 225 | pxq[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( sLPC_Q14[ MAX_LPC_ORDER + i ], Gain_Q10 ), 8 ) ); |
225 | } | 226 | } |
226 | 227 | ||
227 | /* DEBUG_STORE_DATA( dec.pcm, pxq, psDec->subfr_length * sizeof( opus_int16 ) ) */ | ||
228 | |||
229 | /* Update LPC filter state */ | 228 | /* Update LPC filter state */ |
230 | silk_memcpy( sLPC_Q14, &sLPC_Q14[ psDec->subfr_length ], MAX_LPC_ORDER * sizeof( opus_int32 ) ); | 229 | silk_memcpy( sLPC_Q14, &sLPC_Q14[ psDec->subfr_length ], MAX_LPC_ORDER * sizeof( opus_int32 ) ); |
231 | pexc_Q14 += psDec->subfr_length; | 230 | pexc_Q14 += psDec->subfr_length; |
diff --git a/lib/rbcodec/codecs/libopus/silk/decode_frame.c b/lib/rbcodec/codecs/libopus/silk/decode_frame.c index 6a7cffbbe0..e73825b267 100644 --- a/lib/rbcodec/codecs/libopus/silk/decode_frame.c +++ b/lib/rbcodec/codecs/libopus/silk/decode_frame.c | |||
@@ -42,7 +42,8 @@ opus_int silk_decode_frame( | |||
42 | opus_int16 pOut[], /* O Pointer to output speech frame */ | 42 | opus_int16 pOut[], /* O Pointer to output speech frame */ |
43 | opus_int32 *pN, /* O Pointer to size of output frame */ | 43 | opus_int32 *pN, /* O Pointer to size of output frame */ |
44 | opus_int lostFlag, /* I 0: no loss, 1 loss, 2 decode fec */ | 44 | opus_int lostFlag, /* I 0: no loss, 1 loss, 2 decode fec */ |
45 | opus_int condCoding /* I The type of conditional coding to use */ | 45 | opus_int condCoding, /* I The type of conditional coding to use */ |
46 | int arch /* I Run-time architecture */ | ||
46 | ) | 47 | ) |
47 | { | 48 | { |
48 | VARDECL( silk_decoder_control, psDecCtrl ); | 49 | VARDECL( silk_decoder_control, psDecCtrl ); |
@@ -54,7 +55,7 @@ opus_int silk_decode_frame( | |||
54 | psDecCtrl->LTP_scale_Q14 = 0; | 55 | psDecCtrl->LTP_scale_Q14 = 0; |
55 | 56 | ||
56 | /* Safety checks */ | 57 | /* Safety checks */ |
57 | silk_assert( L > 0 && L <= MAX_FRAME_LENGTH ); | 58 | celt_assert( L > 0 && L <= MAX_FRAME_LENGTH ); |
58 | 59 | ||
59 | if( lostFlag == FLAG_DECODE_NORMAL || | 60 | if( lostFlag == FLAG_DECODE_NORMAL || |
60 | ( lostFlag == FLAG_DECODE_LBRR && psDec->LBRR_flags[ psDec->nFramesDecoded ] == 1 ) ) | 61 | ( lostFlag == FLAG_DECODE_LBRR && psDec->LBRR_flags[ psDec->nFramesDecoded ] == 1 ) ) |
@@ -81,28 +82,29 @@ opus_int silk_decode_frame( | |||
81 | /********************************************************/ | 82 | /********************************************************/ |
82 | /* Run inverse NSQ */ | 83 | /* Run inverse NSQ */ |
83 | /********************************************************/ | 84 | /********************************************************/ |
84 | silk_decode_core( psDec, psDecCtrl, pOut, pulses ); | 85 | silk_decode_core( psDec, psDecCtrl, pOut, pulses, arch ); |
85 | 86 | ||
86 | /********************************************************/ | 87 | /********************************************************/ |
87 | /* Update PLC state */ | 88 | /* Update PLC state */ |
88 | /********************************************************/ | 89 | /********************************************************/ |
89 | silk_PLC( psDec, psDecCtrl, pOut, 0 ); | 90 | silk_PLC( psDec, psDecCtrl, pOut, 0, arch ); |
90 | 91 | ||
91 | psDec->lossCnt = 0; | 92 | psDec->lossCnt = 0; |
92 | psDec->prevSignalType = psDec->indices.signalType; | 93 | psDec->prevSignalType = psDec->indices.signalType; |
93 | silk_assert( psDec->prevSignalType >= 0 && psDec->prevSignalType <= 2 ); | 94 | celt_assert( psDec->prevSignalType >= 0 && psDec->prevSignalType <= 2 ); |
94 | 95 | ||
95 | /* A frame has been decoded without errors */ | 96 | /* A frame has been decoded without errors */ |
96 | psDec->first_frame_after_reset = 0; | 97 | psDec->first_frame_after_reset = 0; |
97 | } else { | 98 | } else { |
98 | /* Handle packet loss by extrapolation */ | 99 | /* Handle packet loss by extrapolation */ |
99 | silk_PLC( psDec, psDecCtrl, pOut, 1 ); | 100 | psDec->indices.signalType = psDec->prevSignalType; |
101 | silk_PLC( psDec, psDecCtrl, pOut, 1, arch ); | ||
100 | } | 102 | } |
101 | 103 | ||
102 | /*************************/ | 104 | /*************************/ |
103 | /* Update output buffer. */ | 105 | /* Update output buffer. */ |
104 | /*************************/ | 106 | /*************************/ |
105 | silk_assert( psDec->ltp_mem_length >= psDec->frame_length ); | 107 | celt_assert( psDec->ltp_mem_length >= psDec->frame_length ); |
106 | mv_len = psDec->ltp_mem_length - psDec->frame_length; | 108 | mv_len = psDec->ltp_mem_length - psDec->frame_length; |
107 | silk_memmove( psDec->outBuf, &psDec->outBuf[ psDec->frame_length ], mv_len * sizeof(opus_int16) ); | 109 | silk_memmove( psDec->outBuf, &psDec->outBuf[ psDec->frame_length ], mv_len * sizeof(opus_int16) ); |
108 | silk_memcpy( &psDec->outBuf[ mv_len ], pOut, psDec->frame_length * sizeof( opus_int16 ) ); | 110 | silk_memcpy( &psDec->outBuf[ mv_len ], pOut, psDec->frame_length * sizeof( opus_int16 ) ); |
diff --git a/lib/rbcodec/codecs/libopus/silk/decode_indices.c b/lib/rbcodec/codecs/libopus/silk/decode_indices.c index 7afe5c26c1..0bb4a997a5 100644 --- a/lib/rbcodec/codecs/libopus/silk/decode_indices.c +++ b/lib/rbcodec/codecs/libopus/silk/decode_indices.c | |||
@@ -79,7 +79,7 @@ void silk_decode_indices( | |||
79 | /**********************/ | 79 | /**********************/ |
80 | psDec->indices.NLSFIndices[ 0 ] = (opus_int8)ec_dec_icdf( psRangeDec, &psDec->psNLSF_CB->CB1_iCDF[ ( psDec->indices.signalType >> 1 ) * psDec->psNLSF_CB->nVectors ], 8 ); | 80 | psDec->indices.NLSFIndices[ 0 ] = (opus_int8)ec_dec_icdf( psRangeDec, &psDec->psNLSF_CB->CB1_iCDF[ ( psDec->indices.signalType >> 1 ) * psDec->psNLSF_CB->nVectors ], 8 ); |
81 | silk_NLSF_unpack( ec_ix, pred_Q8, psDec->psNLSF_CB, psDec->indices.NLSFIndices[ 0 ] ); | 81 | silk_NLSF_unpack( ec_ix, pred_Q8, psDec->psNLSF_CB, psDec->indices.NLSFIndices[ 0 ] ); |
82 | silk_assert( psDec->psNLSF_CB->order == psDec->LPC_order ); | 82 | celt_assert( psDec->psNLSF_CB->order == psDec->LPC_order ); |
83 | for( i = 0; i < psDec->psNLSF_CB->order; i++ ) { | 83 | for( i = 0; i < psDec->psNLSF_CB->order; i++ ) { |
84 | Ix = ec_dec_icdf( psRangeDec, &psDec->psNLSF_CB->ec_iCDF[ ec_ix[ i ] ], 8 ); | 84 | Ix = ec_dec_icdf( psRangeDec, &psDec->psNLSF_CB->ec_iCDF[ ec_ix[ i ] ], 8 ); |
85 | if( Ix == 0 ) { | 85 | if( Ix == 0 ) { |
diff --git a/lib/rbcodec/codecs/libopus/silk/decode_parameters.c b/lib/rbcodec/codecs/libopus/silk/decode_parameters.c index e345b1dcef..a56a409858 100644 --- a/lib/rbcodec/codecs/libopus/silk/decode_parameters.c +++ b/lib/rbcodec/codecs/libopus/silk/decode_parameters.c | |||
@@ -52,7 +52,7 @@ void silk_decode_parameters( | |||
52 | silk_NLSF_decode( pNLSF_Q15, psDec->indices.NLSFIndices, psDec->psNLSF_CB ); | 52 | silk_NLSF_decode( pNLSF_Q15, psDec->indices.NLSFIndices, psDec->psNLSF_CB ); |
53 | 53 | ||
54 | /* Convert NLSF parameters to AR prediction filter coefficients */ | 54 | /* Convert NLSF parameters to AR prediction filter coefficients */ |
55 | silk_NLSF2A( psDecCtrl->PredCoef_Q12[ 1 ], pNLSF_Q15, psDec->LPC_order ); | 55 | silk_NLSF2A( psDecCtrl->PredCoef_Q12[ 1 ], pNLSF_Q15, psDec->LPC_order, psDec->arch ); |
56 | 56 | ||
57 | /* If just reset, e.g., because internal Fs changed, do not allow interpolation */ | 57 | /* If just reset, e.g., because internal Fs changed, do not allow interpolation */ |
58 | /* improves the case of packet loss in the first frame after a switch */ | 58 | /* improves the case of packet loss in the first frame after a switch */ |
@@ -69,7 +69,7 @@ void silk_decode_parameters( | |||
69 | } | 69 | } |
70 | 70 | ||
71 | /* Convert NLSF parameters to AR prediction filter coefficients */ | 71 | /* Convert NLSF parameters to AR prediction filter coefficients */ |
72 | silk_NLSF2A( psDecCtrl->PredCoef_Q12[ 0 ], pNLSF0_Q15, psDec->LPC_order ); | 72 | silk_NLSF2A( psDecCtrl->PredCoef_Q12[ 0 ], pNLSF0_Q15, psDec->LPC_order, psDec->arch ); |
73 | } else { | 73 | } else { |
74 | /* Copy LPC coefficients for first half from second half */ | 74 | /* Copy LPC coefficients for first half from second half */ |
75 | silk_memcpy( psDecCtrl->PredCoef_Q12[ 0 ], psDecCtrl->PredCoef_Q12[ 1 ], psDec->LPC_order * sizeof( opus_int16 ) ); | 75 | silk_memcpy( psDecCtrl->PredCoef_Q12[ 0 ], psDecCtrl->PredCoef_Q12[ 1 ], psDec->LPC_order * sizeof( opus_int16 ) ); |
diff --git a/lib/rbcodec/codecs/libopus/silk/decode_pitch.c b/lib/rbcodec/codecs/libopus/silk/decode_pitch.c index fedbc6a525..fd1b6bf551 100644 --- a/lib/rbcodec/codecs/libopus/silk/decode_pitch.c +++ b/lib/rbcodec/codecs/libopus/silk/decode_pitch.c | |||
@@ -51,7 +51,7 @@ void silk_decode_pitch( | |||
51 | Lag_CB_ptr = &silk_CB_lags_stage2[ 0 ][ 0 ]; | 51 | Lag_CB_ptr = &silk_CB_lags_stage2[ 0 ][ 0 ]; |
52 | cbk_size = PE_NB_CBKS_STAGE2_EXT; | 52 | cbk_size = PE_NB_CBKS_STAGE2_EXT; |
53 | } else { | 53 | } else { |
54 | silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1 ); | 54 | celt_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1 ); |
55 | Lag_CB_ptr = &silk_CB_lags_stage2_10_ms[ 0 ][ 0 ]; | 55 | Lag_CB_ptr = &silk_CB_lags_stage2_10_ms[ 0 ][ 0 ]; |
56 | cbk_size = PE_NB_CBKS_STAGE2_10MS; | 56 | cbk_size = PE_NB_CBKS_STAGE2_10MS; |
57 | } | 57 | } |
@@ -60,7 +60,7 @@ void silk_decode_pitch( | |||
60 | Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ]; | 60 | Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ]; |
61 | cbk_size = PE_NB_CBKS_STAGE3_MAX; | 61 | cbk_size = PE_NB_CBKS_STAGE3_MAX; |
62 | } else { | 62 | } else { |
63 | silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1 ); | 63 | celt_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1 ); |
64 | Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ]; | 64 | Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ]; |
65 | cbk_size = PE_NB_CBKS_STAGE3_10MS; | 65 | cbk_size = PE_NB_CBKS_STAGE3_10MS; |
66 | } | 66 | } |
diff --git a/lib/rbcodec/codecs/libopus/silk/decode_pulses.c b/lib/rbcodec/codecs/libopus/silk/decode_pulses.c index 1e14bc37b4..a56d2d3074 100644 --- a/lib/rbcodec/codecs/libopus/silk/decode_pulses.c +++ b/lib/rbcodec/codecs/libopus/silk/decode_pulses.c | |||
@@ -56,7 +56,7 @@ void silk_decode_pulses( | |||
56 | silk_assert( 1 << LOG2_SHELL_CODEC_FRAME_LENGTH == SHELL_CODEC_FRAME_LENGTH ); | 56 | silk_assert( 1 << LOG2_SHELL_CODEC_FRAME_LENGTH == SHELL_CODEC_FRAME_LENGTH ); |
57 | iter = silk_RSHIFT( frame_length, LOG2_SHELL_CODEC_FRAME_LENGTH ); | 57 | iter = silk_RSHIFT( frame_length, LOG2_SHELL_CODEC_FRAME_LENGTH ); |
58 | if( iter * SHELL_CODEC_FRAME_LENGTH < frame_length ) { | 58 | if( iter * SHELL_CODEC_FRAME_LENGTH < frame_length ) { |
59 | silk_assert( frame_length == 12 * 10 ); /* Make sure only happens for 10 ms @ 12 kHz */ | 59 | celt_assert( frame_length == 12 * 10 ); /* Make sure only happens for 10 ms @ 12 kHz */ |
60 | iter++; | 60 | iter++; |
61 | } | 61 | } |
62 | 62 | ||
@@ -69,9 +69,9 @@ void silk_decode_pulses( | |||
69 | sum_pulses[ i ] = ec_dec_icdf( psRangeDec, cdf_ptr, 8 ); | 69 | sum_pulses[ i ] = ec_dec_icdf( psRangeDec, cdf_ptr, 8 ); |
70 | 70 | ||
71 | /* LSB indication */ | 71 | /* LSB indication */ |
72 | while( sum_pulses[ i ] == MAX_PULSES + 1 ) { | 72 | while( sum_pulses[ i ] == SILK_MAX_PULSES + 1 ) { |
73 | nLshifts[ i ]++; | 73 | nLshifts[ i ]++; |
74 | /* When we've already got 10 LSBs, we shift the table to not allow (MAX_PULSES + 1) */ | 74 | /* When we've already got 10 LSBs, we shift the table to not allow (SILK_MAX_PULSES + 1) */ |
75 | sum_pulses[ i ] = ec_dec_icdf( psRangeDec, | 75 | sum_pulses[ i ] = ec_dec_icdf( psRangeDec, |
76 | silk_pulses_per_block_iCDF[ N_RATE_LEVELS - 1] + ( nLshifts[ i ] == 10 ), 8 ); | 76 | silk_pulses_per_block_iCDF[ N_RATE_LEVELS - 1] + ( nLshifts[ i ] == 10 ), 8 ); |
77 | } | 77 | } |
diff --git a/lib/rbcodec/codecs/libopus/silk/decoder_set_fs.c b/lib/rbcodec/codecs/libopus/silk/decoder_set_fs.c index eef0fd25e1..d9a13d0f0c 100644 --- a/lib/rbcodec/codecs/libopus/silk/decoder_set_fs.c +++ b/lib/rbcodec/codecs/libopus/silk/decoder_set_fs.c | |||
@@ -40,8 +40,8 @@ opus_int silk_decoder_set_fs( | |||
40 | { | 40 | { |
41 | opus_int frame_length, ret = 0; | 41 | opus_int frame_length, ret = 0; |
42 | 42 | ||
43 | silk_assert( fs_kHz == 8 || fs_kHz == 12 || fs_kHz == 16 ); | 43 | celt_assert( fs_kHz == 8 || fs_kHz == 12 || fs_kHz == 16 ); |
44 | silk_assert( psDec->nb_subfr == MAX_NB_SUBFR || psDec->nb_subfr == MAX_NB_SUBFR/2 ); | 44 | celt_assert( psDec->nb_subfr == MAX_NB_SUBFR || psDec->nb_subfr == MAX_NB_SUBFR/2 ); |
45 | 45 | ||
46 | /* New (sub)frame length */ | 46 | /* New (sub)frame length */ |
47 | psDec->subfr_length = silk_SMULBB( SUB_FRAME_LENGTH_MS, fs_kHz ); | 47 | psDec->subfr_length = silk_SMULBB( SUB_FRAME_LENGTH_MS, fs_kHz ); |
@@ -86,7 +86,7 @@ opus_int silk_decoder_set_fs( | |||
86 | psDec->pitch_lag_low_bits_iCDF = silk_uniform4_iCDF; | 86 | psDec->pitch_lag_low_bits_iCDF = silk_uniform4_iCDF; |
87 | } else { | 87 | } else { |
88 | /* unsupported sampling rate */ | 88 | /* unsupported sampling rate */ |
89 | silk_assert( 0 ); | 89 | celt_assert( 0 ); |
90 | } | 90 | } |
91 | psDec->first_frame_after_reset = 1; | 91 | psDec->first_frame_after_reset = 1; |
92 | psDec->lagPrev = 100; | 92 | psDec->lagPrev = 100; |
@@ -101,7 +101,7 @@ opus_int silk_decoder_set_fs( | |||
101 | } | 101 | } |
102 | 102 | ||
103 | /* Check that settings are valid */ | 103 | /* Check that settings are valid */ |
104 | silk_assert( psDec->frame_length > 0 && psDec->frame_length <= MAX_FRAME_LENGTH ); | 104 | celt_assert( psDec->frame_length > 0 && psDec->frame_length <= MAX_FRAME_LENGTH ); |
105 | 105 | ||
106 | return ret; | 106 | return ret; |
107 | } | 107 | } |
diff --git a/lib/rbcodec/codecs/libopus/silk/define.h b/lib/rbcodec/codecs/libopus/silk/define.h index c47aca9f58..247cb0bf71 100644 --- a/lib/rbcodec/codecs/libopus/silk/define.h +++ b/lib/rbcodec/codecs/libopus/silk/define.h | |||
@@ -46,7 +46,6 @@ extern "C" | |||
46 | /* Limits on bitrate */ | 46 | /* Limits on bitrate */ |
47 | #define MIN_TARGET_RATE_BPS 5000 | 47 | #define MIN_TARGET_RATE_BPS 5000 |
48 | #define MAX_TARGET_RATE_BPS 80000 | 48 | #define MAX_TARGET_RATE_BPS 80000 |
49 | #define TARGET_RATE_TAB_SZ 8 | ||
50 | 49 | ||
51 | /* LBRR thresholds */ | 50 | /* LBRR thresholds */ |
52 | #define LBRR_NB_MIN_RATE_BPS 12000 | 51 | #define LBRR_NB_MIN_RATE_BPS 12000 |
@@ -56,6 +55,12 @@ extern "C" | |||
56 | /* DTX settings */ | 55 | /* DTX settings */ |
57 | #define NB_SPEECH_FRAMES_BEFORE_DTX 10 /* eq 200 ms */ | 56 | #define NB_SPEECH_FRAMES_BEFORE_DTX 10 /* eq 200 ms */ |
58 | #define MAX_CONSECUTIVE_DTX 20 /* eq 400 ms */ | 57 | #define MAX_CONSECUTIVE_DTX 20 /* eq 400 ms */ |
58 | #define DTX_ACTIVITY_THRESHOLD 0.1f | ||
59 | |||
60 | /* VAD decision */ | ||
61 | #define VAD_NO_DECISION -1 | ||
62 | #define VAD_NO_ACTIVITY 0 | ||
63 | #define VAD_ACTIVITY 1 | ||
59 | 64 | ||
60 | /* Maximum sampling frequency */ | 65 | /* Maximum sampling frequency */ |
61 | #define MAX_FS_KHZ 16 | 66 | #define MAX_FS_KHZ 16 |
@@ -147,7 +152,7 @@ extern "C" | |||
147 | #define USE_HARM_SHAPING 1 | 152 | #define USE_HARM_SHAPING 1 |
148 | 153 | ||
149 | /* Max LPC order of noise shaping filters */ | 154 | /* Max LPC order of noise shaping filters */ |
150 | #define MAX_SHAPE_LPC_ORDER 16 | 155 | #define MAX_SHAPE_LPC_ORDER 24 |
151 | 156 | ||
152 | #define HARM_SHAPE_FIR_TAPS 3 | 157 | #define HARM_SHAPE_FIR_TAPS 3 |
153 | 158 | ||
@@ -157,8 +162,7 @@ extern "C" | |||
157 | #define LTP_BUF_LENGTH 512 | 162 | #define LTP_BUF_LENGTH 512 |
158 | #define LTP_MASK ( LTP_BUF_LENGTH - 1 ) | 163 | #define LTP_MASK ( LTP_BUF_LENGTH - 1 ) |
159 | 164 | ||
160 | #define DECISION_DELAY 32 | 165 | #define DECISION_DELAY 40 |
161 | #define DECISION_DELAY_MASK ( DECISION_DELAY - 1 ) | ||
162 | 166 | ||
163 | /* Number of subframes for excitation entropy coding */ | 167 | /* Number of subframes for excitation entropy coding */ |
164 | #define SHELL_CODEC_FRAME_LENGTH 16 | 168 | #define SHELL_CODEC_FRAME_LENGTH 16 |
@@ -169,15 +173,11 @@ extern "C" | |||
169 | #define N_RATE_LEVELS 10 | 173 | #define N_RATE_LEVELS 10 |
170 | 174 | ||
171 | /* Maximum sum of pulses per shell coding frame */ | 175 | /* Maximum sum of pulses per shell coding frame */ |
172 | #define MAX_PULSES 16 | 176 | #define SILK_MAX_PULSES 16 |
173 | 177 | ||
174 | #define MAX_MATRIX_SIZE MAX_LPC_ORDER /* Max of LPC Order and LTP order */ | 178 | #define MAX_MATRIX_SIZE MAX_LPC_ORDER /* Max of LPC Order and LTP order */ |
175 | 179 | ||
176 | #if( MAX_LPC_ORDER > DECISION_DELAY ) | ||
177 | # define NSQ_LPC_BUF_LENGTH MAX_LPC_ORDER | 180 | # define NSQ_LPC_BUF_LENGTH MAX_LPC_ORDER |
178 | #else | ||
179 | # define NSQ_LPC_BUF_LENGTH DECISION_DELAY | ||
180 | #endif | ||
181 | 181 | ||
182 | /***************************/ | 182 | /***************************/ |
183 | /* Voice activity detector */ | 183 | /* Voice activity detector */ |
@@ -205,7 +205,6 @@ extern "C" | |||
205 | /******************/ | 205 | /******************/ |
206 | #define NLSF_W_Q 2 | 206 | #define NLSF_W_Q 2 |
207 | #define NLSF_VQ_MAX_VECTORS 32 | 207 | #define NLSF_VQ_MAX_VECTORS 32 |
208 | #define NLSF_VQ_MAX_SURVIVORS 32 | ||
209 | #define NLSF_QUANT_MAX_AMPLITUDE 4 | 208 | #define NLSF_QUANT_MAX_AMPLITUDE 4 |
210 | #define NLSF_QUANT_MAX_AMPLITUDE_EXT 10 | 209 | #define NLSF_QUANT_MAX_AMPLITUDE_EXT 10 |
211 | #define NLSF_QUANT_LEVEL_ADJ 0.1 | 210 | #define NLSF_QUANT_LEVEL_ADJ 0.1 |
diff --git a/lib/rbcodec/codecs/libopus/silk/enc_API.c b/lib/rbcodec/codecs/libopus/silk/enc_API.c new file mode 100644 index 0000000000..55a33f37e9 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/enc_API.c | |||
@@ -0,0 +1,576 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | #include "define.h" | ||
32 | #include "API.h" | ||
33 | #include "control.h" | ||
34 | #include "typedef.h" | ||
35 | #include "stack_alloc.h" | ||
36 | #include "structs.h" | ||
37 | #include "tuning_parameters.h" | ||
38 | #ifdef FIXED_POINT | ||
39 | #include "main_FIX.h" | ||
40 | #else | ||
41 | #include "main_FLP.h" | ||
42 | #endif | ||
43 | |||
44 | /***************************************/ | ||
45 | /* Read control structure from encoder */ | ||
46 | /***************************************/ | ||
47 | static opus_int silk_QueryEncoder( /* O Returns error code */ | ||
48 | const void *encState, /* I State */ | ||
49 | silk_EncControlStruct *encStatus /* O Encoder Status */ | ||
50 | ); | ||
51 | |||
52 | /****************************************/ | ||
53 | /* Encoder functions */ | ||
54 | /****************************************/ | ||
55 | |||
56 | opus_int silk_Get_Encoder_Size( /* O Returns error code */ | ||
57 | opus_int *encSizeBytes /* O Number of bytes in SILK encoder state */ | ||
58 | ) | ||
59 | { | ||
60 | opus_int ret = SILK_NO_ERROR; | ||
61 | |||
62 | *encSizeBytes = sizeof( silk_encoder ); | ||
63 | |||
64 | return ret; | ||
65 | } | ||
66 | |||
67 | /*************************/ | ||
68 | /* Init or Reset encoder */ | ||
69 | /*************************/ | ||
70 | opus_int silk_InitEncoder( /* O Returns error code */ | ||
71 | void *encState, /* I/O State */ | ||
72 | int arch, /* I Run-time architecture */ | ||
73 | silk_EncControlStruct *encStatus /* O Encoder Status */ | ||
74 | ) | ||
75 | { | ||
76 | silk_encoder *psEnc; | ||
77 | opus_int n, ret = SILK_NO_ERROR; | ||
78 | |||
79 | psEnc = (silk_encoder *)encState; | ||
80 | |||
81 | /* Reset encoder */ | ||
82 | silk_memset( psEnc, 0, sizeof( silk_encoder ) ); | ||
83 | for( n = 0; n < ENCODER_NUM_CHANNELS; n++ ) { | ||
84 | if( ret += silk_init_encoder( &psEnc->state_Fxx[ n ], arch ) ) { | ||
85 | celt_assert( 0 ); | ||
86 | } | ||
87 | } | ||
88 | |||
89 | psEnc->nChannelsAPI = 1; | ||
90 | psEnc->nChannelsInternal = 1; | ||
91 | |||
92 | /* Read control structure */ | ||
93 | if( ret += silk_QueryEncoder( encState, encStatus ) ) { | ||
94 | celt_assert( 0 ); | ||
95 | } | ||
96 | |||
97 | return ret; | ||
98 | } | ||
99 | |||
100 | /***************************************/ | ||
101 | /* Read control structure from encoder */ | ||
102 | /***************************************/ | ||
103 | static opus_int silk_QueryEncoder( /* O Returns error code */ | ||
104 | const void *encState, /* I State */ | ||
105 | silk_EncControlStruct *encStatus /* O Encoder Status */ | ||
106 | ) | ||
107 | { | ||
108 | opus_int ret = SILK_NO_ERROR; | ||
109 | silk_encoder_state_Fxx *state_Fxx; | ||
110 | silk_encoder *psEnc = (silk_encoder *)encState; | ||
111 | |||
112 | state_Fxx = psEnc->state_Fxx; | ||
113 | |||
114 | encStatus->nChannelsAPI = psEnc->nChannelsAPI; | ||
115 | encStatus->nChannelsInternal = psEnc->nChannelsInternal; | ||
116 | encStatus->API_sampleRate = state_Fxx[ 0 ].sCmn.API_fs_Hz; | ||
117 | encStatus->maxInternalSampleRate = state_Fxx[ 0 ].sCmn.maxInternal_fs_Hz; | ||
118 | encStatus->minInternalSampleRate = state_Fxx[ 0 ].sCmn.minInternal_fs_Hz; | ||
119 | encStatus->desiredInternalSampleRate = state_Fxx[ 0 ].sCmn.desiredInternal_fs_Hz; | ||
120 | encStatus->payloadSize_ms = state_Fxx[ 0 ].sCmn.PacketSize_ms; | ||
121 | encStatus->bitRate = state_Fxx[ 0 ].sCmn.TargetRate_bps; | ||
122 | encStatus->packetLossPercentage = state_Fxx[ 0 ].sCmn.PacketLoss_perc; | ||
123 | encStatus->complexity = state_Fxx[ 0 ].sCmn.Complexity; | ||
124 | encStatus->useInBandFEC = state_Fxx[ 0 ].sCmn.useInBandFEC; | ||
125 | encStatus->useDTX = state_Fxx[ 0 ].sCmn.useDTX; | ||
126 | encStatus->useCBR = state_Fxx[ 0 ].sCmn.useCBR; | ||
127 | encStatus->internalSampleRate = silk_SMULBB( state_Fxx[ 0 ].sCmn.fs_kHz, 1000 ); | ||
128 | encStatus->allowBandwidthSwitch = state_Fxx[ 0 ].sCmn.allow_bandwidth_switch; | ||
129 | encStatus->inWBmodeWithoutVariableLP = state_Fxx[ 0 ].sCmn.fs_kHz == 16 && state_Fxx[ 0 ].sCmn.sLP.mode == 0; | ||
130 | |||
131 | return ret; | ||
132 | } | ||
133 | |||
134 | |||
135 | /**************************/ | ||
136 | /* Encode frame with Silk */ | ||
137 | /**************************/ | ||
138 | /* Note: if prefillFlag is set, the input must contain 10 ms of audio, irrespective of what */ | ||
139 | /* encControl->payloadSize_ms is set to */ | ||
140 | opus_int silk_Encode( /* O Returns error code */ | ||
141 | void *encState, /* I/O State */ | ||
142 | silk_EncControlStruct *encControl, /* I Control status */ | ||
143 | const opus_int16 *samplesIn, /* I Speech sample input vector */ | ||
144 | opus_int nSamplesIn, /* I Number of samples in input vector */ | ||
145 | ec_enc *psRangeEnc, /* I/O Compressor data structure */ | ||
146 | opus_int32 *nBytesOut, /* I/O Number of bytes in payload (input: Max bytes) */ | ||
147 | const opus_int prefillFlag, /* I Flag to indicate prefilling buffers no coding */ | ||
148 | opus_int activity /* I Decision of Opus voice activity detector */ | ||
149 | ) | ||
150 | { | ||
151 | opus_int n, i, nBits, flags, tmp_payloadSize_ms = 0, tmp_complexity = 0, ret = 0; | ||
152 | opus_int nSamplesToBuffer, nSamplesToBufferMax, nBlocksOf10ms; | ||
153 | opus_int nSamplesFromInput = 0, nSamplesFromInputMax; | ||
154 | opus_int speech_act_thr_for_switch_Q8; | ||
155 | opus_int32 TargetRate_bps, MStargetRates_bps[ 2 ], channelRate_bps, LBRR_symbol, sum; | ||
156 | silk_encoder *psEnc = ( silk_encoder * )encState; | ||
157 | VARDECL( opus_int16, buf ); | ||
158 | opus_int transition, curr_block, tot_blocks; | ||
159 | SAVE_STACK; | ||
160 | |||
161 | if (encControl->reducedDependency) | ||
162 | { | ||
163 | psEnc->state_Fxx[0].sCmn.first_frame_after_reset = 1; | ||
164 | psEnc->state_Fxx[1].sCmn.first_frame_after_reset = 1; | ||
165 | } | ||
166 | psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded = psEnc->state_Fxx[ 1 ].sCmn.nFramesEncoded = 0; | ||
167 | |||
168 | /* Check values in encoder control structure */ | ||
169 | if( ( ret = check_control_input( encControl ) ) != 0 ) { | ||
170 | celt_assert( 0 ); | ||
171 | RESTORE_STACK; | ||
172 | return ret; | ||
173 | } | ||
174 | |||
175 | encControl->switchReady = 0; | ||
176 | |||
177 | if( encControl->nChannelsInternal > psEnc->nChannelsInternal ) { | ||
178 | /* Mono -> Stereo transition: init state of second channel and stereo state */ | ||
179 | ret += silk_init_encoder( &psEnc->state_Fxx[ 1 ], psEnc->state_Fxx[ 0 ].sCmn.arch ); | ||
180 | silk_memset( psEnc->sStereo.pred_prev_Q13, 0, sizeof( psEnc->sStereo.pred_prev_Q13 ) ); | ||
181 | silk_memset( psEnc->sStereo.sSide, 0, sizeof( psEnc->sStereo.sSide ) ); | ||
182 | psEnc->sStereo.mid_side_amp_Q0[ 0 ] = 0; | ||
183 | psEnc->sStereo.mid_side_amp_Q0[ 1 ] = 1; | ||
184 | psEnc->sStereo.mid_side_amp_Q0[ 2 ] = 0; | ||
185 | psEnc->sStereo.mid_side_amp_Q0[ 3 ] = 1; | ||
186 | psEnc->sStereo.width_prev_Q14 = 0; | ||
187 | psEnc->sStereo.smth_width_Q14 = SILK_FIX_CONST( 1, 14 ); | ||
188 | if( psEnc->nChannelsAPI == 2 ) { | ||
189 | silk_memcpy( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state, &psEnc->state_Fxx[ 0 ].sCmn.resampler_state, sizeof( silk_resampler_state_struct ) ); | ||
190 | silk_memcpy( &psEnc->state_Fxx[ 1 ].sCmn.In_HP_State, &psEnc->state_Fxx[ 0 ].sCmn.In_HP_State, sizeof( psEnc->state_Fxx[ 1 ].sCmn.In_HP_State ) ); | ||
191 | } | ||
192 | } | ||
193 | |||
194 | transition = (encControl->payloadSize_ms != psEnc->state_Fxx[ 0 ].sCmn.PacketSize_ms) || (psEnc->nChannelsInternal != encControl->nChannelsInternal); | ||
195 | |||
196 | psEnc->nChannelsAPI = encControl->nChannelsAPI; | ||
197 | psEnc->nChannelsInternal = encControl->nChannelsInternal; | ||
198 | |||
199 | nBlocksOf10ms = silk_DIV32( 100 * nSamplesIn, encControl->API_sampleRate ); | ||
200 | tot_blocks = ( nBlocksOf10ms > 1 ) ? nBlocksOf10ms >> 1 : 1; | ||
201 | curr_block = 0; | ||
202 | if( prefillFlag ) { | ||
203 | silk_LP_state save_LP; | ||
204 | /* Only accept input length of 10 ms */ | ||
205 | if( nBlocksOf10ms != 1 ) { | ||
206 | celt_assert( 0 ); | ||
207 | RESTORE_STACK; | ||
208 | return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES; | ||
209 | } | ||
210 | if ( prefillFlag == 2 ) { | ||
211 | save_LP = psEnc->state_Fxx[ 0 ].sCmn.sLP; | ||
212 | /* Save the sampling rate so the bandwidth switching code can keep handling transitions. */ | ||
213 | save_LP.saved_fs_kHz = psEnc->state_Fxx[ 0 ].sCmn.fs_kHz; | ||
214 | } | ||
215 | /* Reset Encoder */ | ||
216 | for( n = 0; n < encControl->nChannelsInternal; n++ ) { | ||
217 | ret = silk_init_encoder( &psEnc->state_Fxx[ n ], psEnc->state_Fxx[ n ].sCmn.arch ); | ||
218 | /* Restore the variable LP state. */ | ||
219 | if ( prefillFlag == 2 ) { | ||
220 | psEnc->state_Fxx[ n ].sCmn.sLP = save_LP; | ||
221 | } | ||
222 | celt_assert( !ret ); | ||
223 | } | ||
224 | tmp_payloadSize_ms = encControl->payloadSize_ms; | ||
225 | encControl->payloadSize_ms = 10; | ||
226 | tmp_complexity = encControl->complexity; | ||
227 | encControl->complexity = 0; | ||
228 | for( n = 0; n < encControl->nChannelsInternal; n++ ) { | ||
229 | psEnc->state_Fxx[ n ].sCmn.controlled_since_last_payload = 0; | ||
230 | psEnc->state_Fxx[ n ].sCmn.prefillFlag = 1; | ||
231 | } | ||
232 | } else { | ||
233 | /* Only accept input lengths that are a multiple of 10 ms */ | ||
234 | if( nBlocksOf10ms * encControl->API_sampleRate != 100 * nSamplesIn || nSamplesIn < 0 ) { | ||
235 | celt_assert( 0 ); | ||
236 | RESTORE_STACK; | ||
237 | return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES; | ||
238 | } | ||
239 | /* Make sure no more than one packet can be produced */ | ||
240 | if( 1000 * (opus_int32)nSamplesIn > encControl->payloadSize_ms * encControl->API_sampleRate ) { | ||
241 | celt_assert( 0 ); | ||
242 | RESTORE_STACK; | ||
243 | return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES; | ||
244 | } | ||
245 | } | ||
246 | |||
247 | for( n = 0; n < encControl->nChannelsInternal; n++ ) { | ||
248 | /* Force the side channel to the same rate as the mid */ | ||
249 | opus_int force_fs_kHz = (n==1) ? psEnc->state_Fxx[0].sCmn.fs_kHz : 0; | ||
250 | if( ( ret = silk_control_encoder( &psEnc->state_Fxx[ n ], encControl, psEnc->allowBandwidthSwitch, n, force_fs_kHz ) ) != 0 ) { | ||
251 | silk_assert( 0 ); | ||
252 | RESTORE_STACK; | ||
253 | return ret; | ||
254 | } | ||
255 | if( psEnc->state_Fxx[n].sCmn.first_frame_after_reset || transition ) { | ||
256 | for( i = 0; i < psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket; i++ ) { | ||
257 | psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i ] = 0; | ||
258 | } | ||
259 | } | ||
260 | psEnc->state_Fxx[ n ].sCmn.inDTX = psEnc->state_Fxx[ n ].sCmn.useDTX; | ||
261 | } | ||
262 | celt_assert( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 0 ].sCmn.fs_kHz == psEnc->state_Fxx[ 1 ].sCmn.fs_kHz ); | ||
263 | |||
264 | /* Input buffering/resampling and encoding */ | ||
265 | nSamplesToBufferMax = | ||
266 | 10 * nBlocksOf10ms * psEnc->state_Fxx[ 0 ].sCmn.fs_kHz; | ||
267 | nSamplesFromInputMax = | ||
268 | silk_DIV32_16( nSamplesToBufferMax * | ||
269 | psEnc->state_Fxx[ 0 ].sCmn.API_fs_Hz, | ||
270 | psEnc->state_Fxx[ 0 ].sCmn.fs_kHz * 1000 ); | ||
271 | ALLOC( buf, nSamplesFromInputMax, opus_int16 ); | ||
272 | while( 1 ) { | ||
273 | nSamplesToBuffer = psEnc->state_Fxx[ 0 ].sCmn.frame_length - psEnc->state_Fxx[ 0 ].sCmn.inputBufIx; | ||
274 | nSamplesToBuffer = silk_min( nSamplesToBuffer, nSamplesToBufferMax ); | ||
275 | nSamplesFromInput = silk_DIV32_16( nSamplesToBuffer * psEnc->state_Fxx[ 0 ].sCmn.API_fs_Hz, psEnc->state_Fxx[ 0 ].sCmn.fs_kHz * 1000 ); | ||
276 | /* Resample and write to buffer */ | ||
277 | if( encControl->nChannelsAPI == 2 && encControl->nChannelsInternal == 2 ) { | ||
278 | opus_int id = psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded; | ||
279 | for( n = 0; n < nSamplesFromInput; n++ ) { | ||
280 | buf[ n ] = samplesIn[ 2 * n ]; | ||
281 | } | ||
282 | /* Making sure to start both resamplers from the same state when switching from mono to stereo */ | ||
283 | if( psEnc->nPrevChannelsInternal == 1 && id==0 ) { | ||
284 | silk_memcpy( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state, &psEnc->state_Fxx[ 0 ].sCmn.resampler_state, sizeof(psEnc->state_Fxx[ 1 ].sCmn.resampler_state)); | ||
285 | } | ||
286 | |||
287 | ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state, | ||
288 | &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput ); | ||
289 | psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer; | ||
290 | |||
291 | nSamplesToBuffer = psEnc->state_Fxx[ 1 ].sCmn.frame_length - psEnc->state_Fxx[ 1 ].sCmn.inputBufIx; | ||
292 | nSamplesToBuffer = silk_min( nSamplesToBuffer, 10 * nBlocksOf10ms * psEnc->state_Fxx[ 1 ].sCmn.fs_kHz ); | ||
293 | for( n = 0; n < nSamplesFromInput; n++ ) { | ||
294 | buf[ n ] = samplesIn[ 2 * n + 1 ]; | ||
295 | } | ||
296 | ret += silk_resampler( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state, | ||
297 | &psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ psEnc->state_Fxx[ 1 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput ); | ||
298 | |||
299 | psEnc->state_Fxx[ 1 ].sCmn.inputBufIx += nSamplesToBuffer; | ||
300 | } else if( encControl->nChannelsAPI == 2 && encControl->nChannelsInternal == 1 ) { | ||
301 | /* Combine left and right channels before resampling */ | ||
302 | for( n = 0; n < nSamplesFromInput; n++ ) { | ||
303 | sum = samplesIn[ 2 * n ] + samplesIn[ 2 * n + 1 ]; | ||
304 | buf[ n ] = (opus_int16)silk_RSHIFT_ROUND( sum, 1 ); | ||
305 | } | ||
306 | ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state, | ||
307 | &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput ); | ||
308 | /* On the first mono frame, average the results for the two resampler states */ | ||
309 | if( psEnc->nPrevChannelsInternal == 2 && psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded == 0 ) { | ||
310 | ret += silk_resampler( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state, | ||
311 | &psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ psEnc->state_Fxx[ 1 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput ); | ||
312 | for( n = 0; n < psEnc->state_Fxx[ 0 ].sCmn.frame_length; n++ ) { | ||
313 | psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx+n+2 ] = | ||
314 | silk_RSHIFT(psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx+n+2 ] | ||
315 | + psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ psEnc->state_Fxx[ 1 ].sCmn.inputBufIx+n+2 ], 1); | ||
316 | } | ||
317 | } | ||
318 | psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer; | ||
319 | } else { | ||
320 | celt_assert( encControl->nChannelsAPI == 1 && encControl->nChannelsInternal == 1 ); | ||
321 | silk_memcpy(buf, samplesIn, nSamplesFromInput*sizeof(opus_int16)); | ||
322 | ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state, | ||
323 | &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput ); | ||
324 | psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer; | ||
325 | } | ||
326 | |||
327 | samplesIn += nSamplesFromInput * encControl->nChannelsAPI; | ||
328 | nSamplesIn -= nSamplesFromInput; | ||
329 | |||
330 | /* Default */ | ||
331 | psEnc->allowBandwidthSwitch = 0; | ||
332 | |||
333 | /* Silk encoder */ | ||
334 | if( psEnc->state_Fxx[ 0 ].sCmn.inputBufIx >= psEnc->state_Fxx[ 0 ].sCmn.frame_length ) { | ||
335 | /* Enough data in input buffer, so encode */ | ||
336 | celt_assert( psEnc->state_Fxx[ 0 ].sCmn.inputBufIx == psEnc->state_Fxx[ 0 ].sCmn.frame_length ); | ||
337 | celt_assert( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 1 ].sCmn.inputBufIx == psEnc->state_Fxx[ 1 ].sCmn.frame_length ); | ||
338 | |||
339 | /* Deal with LBRR data */ | ||
340 | if( psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded == 0 && !prefillFlag ) { | ||
341 | /* Create space at start of payload for VAD and FEC flags */ | ||
342 | opus_uint8 iCDF[ 2 ] = { 0, 0 }; | ||
343 | iCDF[ 0 ] = 256 - silk_RSHIFT( 256, ( psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket + 1 ) * encControl->nChannelsInternal ); | ||
344 | ec_enc_icdf( psRangeEnc, 0, iCDF, 8 ); | ||
345 | |||
346 | /* Encode any LBRR data from previous packet */ | ||
347 | /* Encode LBRR flags */ | ||
348 | for( n = 0; n < encControl->nChannelsInternal; n++ ) { | ||
349 | LBRR_symbol = 0; | ||
350 | for( i = 0; i < psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket; i++ ) { | ||
351 | LBRR_symbol |= silk_LSHIFT( psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i ], i ); | ||
352 | } | ||
353 | psEnc->state_Fxx[ n ].sCmn.LBRR_flag = LBRR_symbol > 0 ? 1 : 0; | ||
354 | if( LBRR_symbol && psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket > 1 ) { | ||
355 | ec_enc_icdf( psRangeEnc, LBRR_symbol - 1, silk_LBRR_flags_iCDF_ptr[ psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket - 2 ], 8 ); | ||
356 | } | ||
357 | } | ||
358 | |||
359 | /* Code LBRR indices and excitation signals */ | ||
360 | for( i = 0; i < psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket; i++ ) { | ||
361 | for( n = 0; n < encControl->nChannelsInternal; n++ ) { | ||
362 | if( psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i ] ) { | ||
363 | opus_int condCoding; | ||
364 | |||
365 | if( encControl->nChannelsInternal == 2 && n == 0 ) { | ||
366 | silk_stereo_encode_pred( psRangeEnc, psEnc->sStereo.predIx[ i ] ); | ||
367 | /* For LBRR data there's no need to code the mid-only flag if the side-channel LBRR flag is set */ | ||
368 | if( psEnc->state_Fxx[ 1 ].sCmn.LBRR_flags[ i ] == 0 ) { | ||
369 | silk_stereo_encode_mid_only( psRangeEnc, psEnc->sStereo.mid_only_flags[ i ] ); | ||
370 | } | ||
371 | } | ||
372 | /* Use conditional coding if previous frame available */ | ||
373 | if( i > 0 && psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i - 1 ] ) { | ||
374 | condCoding = CODE_CONDITIONALLY; | ||
375 | } else { | ||
376 | condCoding = CODE_INDEPENDENTLY; | ||
377 | } | ||
378 | silk_encode_indices( &psEnc->state_Fxx[ n ].sCmn, psRangeEnc, i, 1, condCoding ); | ||
379 | silk_encode_pulses( psRangeEnc, psEnc->state_Fxx[ n ].sCmn.indices_LBRR[i].signalType, psEnc->state_Fxx[ n ].sCmn.indices_LBRR[i].quantOffsetType, | ||
380 | psEnc->state_Fxx[ n ].sCmn.pulses_LBRR[ i ], psEnc->state_Fxx[ n ].sCmn.frame_length ); | ||
381 | } | ||
382 | } | ||
383 | } | ||
384 | |||
385 | /* Reset LBRR flags */ | ||
386 | for( n = 0; n < encControl->nChannelsInternal; n++ ) { | ||
387 | silk_memset( psEnc->state_Fxx[ n ].sCmn.LBRR_flags, 0, sizeof( psEnc->state_Fxx[ n ].sCmn.LBRR_flags ) ); | ||
388 | } | ||
389 | |||
390 | psEnc->nBitsUsedLBRR = ec_tell( psRangeEnc ); | ||
391 | } | ||
392 | |||
393 | silk_HP_variable_cutoff( psEnc->state_Fxx ); | ||
394 | |||
395 | /* Total target bits for packet */ | ||
396 | nBits = silk_DIV32_16( silk_MUL( encControl->bitRate, encControl->payloadSize_ms ), 1000 ); | ||
397 | /* Subtract bits used for LBRR */ | ||
398 | if( !prefillFlag ) { | ||
399 | nBits -= psEnc->nBitsUsedLBRR; | ||
400 | } | ||
401 | /* Divide by number of uncoded frames left in packet */ | ||
402 | nBits = silk_DIV32_16( nBits, psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket ); | ||
403 | /* Convert to bits/second */ | ||
404 | if( encControl->payloadSize_ms == 10 ) { | ||
405 | TargetRate_bps = silk_SMULBB( nBits, 100 ); | ||
406 | } else { | ||
407 | TargetRate_bps = silk_SMULBB( nBits, 50 ); | ||
408 | } | ||
409 | /* Subtract fraction of bits in excess of target in previous frames and packets */ | ||
410 | TargetRate_bps -= silk_DIV32_16( silk_MUL( psEnc->nBitsExceeded, 1000 ), BITRESERVOIR_DECAY_TIME_MS ); | ||
411 | if( !prefillFlag && psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded > 0 ) { | ||
412 | /* Compare actual vs target bits so far in this packet */ | ||
413 | opus_int32 bitsBalance = ec_tell( psRangeEnc ) - psEnc->nBitsUsedLBRR - nBits * psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded; | ||
414 | TargetRate_bps -= silk_DIV32_16( silk_MUL( bitsBalance, 1000 ), BITRESERVOIR_DECAY_TIME_MS ); | ||
415 | } | ||
416 | /* Never exceed input bitrate */ | ||
417 | TargetRate_bps = silk_LIMIT( TargetRate_bps, encControl->bitRate, 5000 ); | ||
418 | |||
419 | /* Convert Left/Right to Mid/Side */ | ||
420 | if( encControl->nChannelsInternal == 2 ) { | ||
421 | silk_stereo_LR_to_MS( &psEnc->sStereo, &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ 2 ], &psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ 2 ], | ||
422 | psEnc->sStereo.predIx[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ], &psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ], | ||
423 | MStargetRates_bps, TargetRate_bps, psEnc->state_Fxx[ 0 ].sCmn.speech_activity_Q8, encControl->toMono, | ||
424 | psEnc->state_Fxx[ 0 ].sCmn.fs_kHz, psEnc->state_Fxx[ 0 ].sCmn.frame_length ); | ||
425 | if( psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] == 0 ) { | ||
426 | /* Reset side channel encoder memory for first frame with side coding */ | ||
427 | if( psEnc->prev_decode_only_middle == 1 ) { | ||
428 | silk_memset( &psEnc->state_Fxx[ 1 ].sShape, 0, sizeof( psEnc->state_Fxx[ 1 ].sShape ) ); | ||
429 | silk_memset( &psEnc->state_Fxx[ 1 ].sCmn.sNSQ, 0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.sNSQ ) ); | ||
430 | silk_memset( psEnc->state_Fxx[ 1 ].sCmn.prev_NLSFq_Q15, 0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.prev_NLSFq_Q15 ) ); | ||
431 | silk_memset( &psEnc->state_Fxx[ 1 ].sCmn.sLP.In_LP_State, 0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.sLP.In_LP_State ) ); | ||
432 | psEnc->state_Fxx[ 1 ].sCmn.prevLag = 100; | ||
433 | psEnc->state_Fxx[ 1 ].sCmn.sNSQ.lagPrev = 100; | ||
434 | psEnc->state_Fxx[ 1 ].sShape.LastGainIndex = 10; | ||
435 | psEnc->state_Fxx[ 1 ].sCmn.prevSignalType = TYPE_NO_VOICE_ACTIVITY; | ||
436 | psEnc->state_Fxx[ 1 ].sCmn.sNSQ.prev_gain_Q16 = 65536; | ||
437 | psEnc->state_Fxx[ 1 ].sCmn.first_frame_after_reset = 1; | ||
438 | } | ||
439 | silk_encode_do_VAD_Fxx( &psEnc->state_Fxx[ 1 ], activity ); | ||
440 | } else { | ||
441 | psEnc->state_Fxx[ 1 ].sCmn.VAD_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] = 0; | ||
442 | } | ||
443 | if( !prefillFlag ) { | ||
444 | silk_stereo_encode_pred( psRangeEnc, psEnc->sStereo.predIx[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] ); | ||
445 | if( psEnc->state_Fxx[ 1 ].sCmn.VAD_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] == 0 ) { | ||
446 | silk_stereo_encode_mid_only( psRangeEnc, psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] ); | ||
447 | } | ||
448 | } | ||
449 | } else { | ||
450 | /* Buffering */ | ||
451 | silk_memcpy( psEnc->state_Fxx[ 0 ].sCmn.inputBuf, psEnc->sStereo.sMid, 2 * sizeof( opus_int16 ) ); | ||
452 | silk_memcpy( psEnc->sStereo.sMid, &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.frame_length ], 2 * sizeof( opus_int16 ) ); | ||
453 | } | ||
454 | silk_encode_do_VAD_Fxx( &psEnc->state_Fxx[ 0 ], activity ); | ||
455 | |||
456 | /* Encode */ | ||
457 | for( n = 0; n < encControl->nChannelsInternal; n++ ) { | ||
458 | opus_int maxBits, useCBR; | ||
459 | |||
460 | /* Handling rate constraints */ | ||
461 | maxBits = encControl->maxBits; | ||
462 | if( tot_blocks == 2 && curr_block == 0 ) { | ||
463 | maxBits = maxBits * 3 / 5; | ||
464 | } else if( tot_blocks == 3 ) { | ||
465 | if( curr_block == 0 ) { | ||
466 | maxBits = maxBits * 2 / 5; | ||
467 | } else if( curr_block == 1 ) { | ||
468 | maxBits = maxBits * 3 / 4; | ||
469 | } | ||
470 | } | ||
471 | useCBR = encControl->useCBR && curr_block == tot_blocks - 1; | ||
472 | |||
473 | if( encControl->nChannelsInternal == 1 ) { | ||
474 | channelRate_bps = TargetRate_bps; | ||
475 | } else { | ||
476 | channelRate_bps = MStargetRates_bps[ n ]; | ||
477 | if( n == 0 && MStargetRates_bps[ 1 ] > 0 ) { | ||
478 | useCBR = 0; | ||
479 | /* Give mid up to 1/2 of the max bits for that frame */ | ||
480 | maxBits -= encControl->maxBits / ( tot_blocks * 2 ); | ||
481 | } | ||
482 | } | ||
483 | |||
484 | if( channelRate_bps > 0 ) { | ||
485 | opus_int condCoding; | ||
486 | |||
487 | silk_control_SNR( &psEnc->state_Fxx[ n ].sCmn, channelRate_bps ); | ||
488 | |||
489 | /* Use independent coding if no previous frame available */ | ||
490 | if( psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded - n <= 0 ) { | ||
491 | condCoding = CODE_INDEPENDENTLY; | ||
492 | } else if( n > 0 && psEnc->prev_decode_only_middle ) { | ||
493 | /* If we skipped a side frame in this packet, we don't | ||
494 | need LTP scaling; the LTP state is well-defined. */ | ||
495 | condCoding = CODE_INDEPENDENTLY_NO_LTP_SCALING; | ||
496 | } else { | ||
497 | condCoding = CODE_CONDITIONALLY; | ||
498 | } | ||
499 | if( ( ret = silk_encode_frame_Fxx( &psEnc->state_Fxx[ n ], nBytesOut, psRangeEnc, condCoding, maxBits, useCBR ) ) != 0 ) { | ||
500 | silk_assert( 0 ); | ||
501 | } | ||
502 | } | ||
503 | psEnc->state_Fxx[ n ].sCmn.controlled_since_last_payload = 0; | ||
504 | psEnc->state_Fxx[ n ].sCmn.inputBufIx = 0; | ||
505 | psEnc->state_Fxx[ n ].sCmn.nFramesEncoded++; | ||
506 | } | ||
507 | psEnc->prev_decode_only_middle = psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded - 1 ]; | ||
508 | |||
509 | /* Insert VAD and FEC flags at beginning of bitstream */ | ||
510 | if( *nBytesOut > 0 && psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded == psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket) { | ||
511 | flags = 0; | ||
512 | for( n = 0; n < encControl->nChannelsInternal; n++ ) { | ||
513 | for( i = 0; i < psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket; i++ ) { | ||
514 | flags = silk_LSHIFT( flags, 1 ); | ||
515 | flags |= psEnc->state_Fxx[ n ].sCmn.VAD_flags[ i ]; | ||
516 | } | ||
517 | flags = silk_LSHIFT( flags, 1 ); | ||
518 | flags |= psEnc->state_Fxx[ n ].sCmn.LBRR_flag; | ||
519 | } | ||
520 | if( !prefillFlag ) { | ||
521 | ec_enc_patch_initial_bits( psRangeEnc, flags, ( psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket + 1 ) * encControl->nChannelsInternal ); | ||
522 | } | ||
523 | |||
524 | /* Return zero bytes if all channels DTXed */ | ||
525 | if( psEnc->state_Fxx[ 0 ].sCmn.inDTX && ( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 1 ].sCmn.inDTX ) ) { | ||
526 | *nBytesOut = 0; | ||
527 | } | ||
528 | |||
529 | psEnc->nBitsExceeded += *nBytesOut * 8; | ||
530 | psEnc->nBitsExceeded -= silk_DIV32_16( silk_MUL( encControl->bitRate, encControl->payloadSize_ms ), 1000 ); | ||
531 | psEnc->nBitsExceeded = silk_LIMIT( psEnc->nBitsExceeded, 0, 10000 ); | ||
532 | |||
533 | /* Update flag indicating if bandwidth switching is allowed */ | ||
534 | speech_act_thr_for_switch_Q8 = silk_SMLAWB( SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ), | ||
535 | SILK_FIX_CONST( ( 1 - SPEECH_ACTIVITY_DTX_THRES ) / MAX_BANDWIDTH_SWITCH_DELAY_MS, 16 + 8 ), psEnc->timeSinceSwitchAllowed_ms ); | ||
536 | if( psEnc->state_Fxx[ 0 ].sCmn.speech_activity_Q8 < speech_act_thr_for_switch_Q8 ) { | ||
537 | psEnc->allowBandwidthSwitch = 1; | ||
538 | psEnc->timeSinceSwitchAllowed_ms = 0; | ||
539 | } else { | ||
540 | psEnc->allowBandwidthSwitch = 0; | ||
541 | psEnc->timeSinceSwitchAllowed_ms += encControl->payloadSize_ms; | ||
542 | } | ||
543 | } | ||
544 | |||
545 | if( nSamplesIn == 0 ) { | ||
546 | break; | ||
547 | } | ||
548 | } else { | ||
549 | break; | ||
550 | } | ||
551 | curr_block++; | ||
552 | } | ||
553 | |||
554 | psEnc->nPrevChannelsInternal = encControl->nChannelsInternal; | ||
555 | |||
556 | encControl->allowBandwidthSwitch = psEnc->allowBandwidthSwitch; | ||
557 | encControl->inWBmodeWithoutVariableLP = psEnc->state_Fxx[ 0 ].sCmn.fs_kHz == 16 && psEnc->state_Fxx[ 0 ].sCmn.sLP.mode == 0; | ||
558 | encControl->internalSampleRate = silk_SMULBB( psEnc->state_Fxx[ 0 ].sCmn.fs_kHz, 1000 ); | ||
559 | encControl->stereoWidth_Q14 = encControl->toMono ? 0 : psEnc->sStereo.smth_width_Q14; | ||
560 | if( prefillFlag ) { | ||
561 | encControl->payloadSize_ms = tmp_payloadSize_ms; | ||
562 | encControl->complexity = tmp_complexity; | ||
563 | for( n = 0; n < encControl->nChannelsInternal; n++ ) { | ||
564 | psEnc->state_Fxx[ n ].sCmn.controlled_since_last_payload = 0; | ||
565 | psEnc->state_Fxx[ n ].sCmn.prefillFlag = 0; | ||
566 | } | ||
567 | } | ||
568 | |||
569 | encControl->signalType = psEnc->state_Fxx[0].sCmn.indices.signalType; | ||
570 | encControl->offset = silk_Quantization_Offsets_Q10 | ||
571 | [ psEnc->state_Fxx[0].sCmn.indices.signalType >> 1 ] | ||
572 | [ psEnc->state_Fxx[0].sCmn.indices.quantOffsetType ]; | ||
573 | RESTORE_STACK; | ||
574 | return ret; | ||
575 | } | ||
576 | |||
diff --git a/lib/rbcodec/codecs/libopus/silk/encode_indices.c b/lib/rbcodec/codecs/libopus/silk/encode_indices.c new file mode 100644 index 0000000000..4bcbc3347b --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/encode_indices.c | |||
@@ -0,0 +1,181 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main.h" | ||
33 | |||
34 | /* Encode side-information parameters to payload */ | ||
35 | void silk_encode_indices( | ||
36 | silk_encoder_state *psEncC, /* I/O Encoder state */ | ||
37 | ec_enc *psRangeEnc, /* I/O Compressor data structure */ | ||
38 | opus_int FrameIndex, /* I Frame number */ | ||
39 | opus_int encode_LBRR, /* I Flag indicating LBRR data is being encoded */ | ||
40 | opus_int condCoding /* I The type of conditional coding to use */ | ||
41 | ) | ||
42 | { | ||
43 | opus_int i, k, typeOffset; | ||
44 | opus_int encode_absolute_lagIndex, delta_lagIndex; | ||
45 | opus_int16 ec_ix[ MAX_LPC_ORDER ]; | ||
46 | opus_uint8 pred_Q8[ MAX_LPC_ORDER ]; | ||
47 | const SideInfoIndices *psIndices; | ||
48 | |||
49 | if( encode_LBRR ) { | ||
50 | psIndices = &psEncC->indices_LBRR[ FrameIndex ]; | ||
51 | } else { | ||
52 | psIndices = &psEncC->indices; | ||
53 | } | ||
54 | |||
55 | /*******************************************/ | ||
56 | /* Encode signal type and quantizer offset */ | ||
57 | /*******************************************/ | ||
58 | typeOffset = 2 * psIndices->signalType + psIndices->quantOffsetType; | ||
59 | celt_assert( typeOffset >= 0 && typeOffset < 6 ); | ||
60 | celt_assert( encode_LBRR == 0 || typeOffset >= 2 ); | ||
61 | if( encode_LBRR || typeOffset >= 2 ) { | ||
62 | ec_enc_icdf( psRangeEnc, typeOffset - 2, silk_type_offset_VAD_iCDF, 8 ); | ||
63 | } else { | ||
64 | ec_enc_icdf( psRangeEnc, typeOffset, silk_type_offset_no_VAD_iCDF, 8 ); | ||
65 | } | ||
66 | |||
67 | /****************/ | ||
68 | /* Encode gains */ | ||
69 | /****************/ | ||
70 | /* first subframe */ | ||
71 | if( condCoding == CODE_CONDITIONALLY ) { | ||
72 | /* conditional coding */ | ||
73 | silk_assert( psIndices->GainsIndices[ 0 ] >= 0 && psIndices->GainsIndices[ 0 ] < MAX_DELTA_GAIN_QUANT - MIN_DELTA_GAIN_QUANT + 1 ); | ||
74 | ec_enc_icdf( psRangeEnc, psIndices->GainsIndices[ 0 ], silk_delta_gain_iCDF, 8 ); | ||
75 | } else { | ||
76 | /* independent coding, in two stages: MSB bits followed by 3 LSBs */ | ||
77 | silk_assert( psIndices->GainsIndices[ 0 ] >= 0 && psIndices->GainsIndices[ 0 ] < N_LEVELS_QGAIN ); | ||
78 | ec_enc_icdf( psRangeEnc, silk_RSHIFT( psIndices->GainsIndices[ 0 ], 3 ), silk_gain_iCDF[ psIndices->signalType ], 8 ); | ||
79 | ec_enc_icdf( psRangeEnc, psIndices->GainsIndices[ 0 ] & 7, silk_uniform8_iCDF, 8 ); | ||
80 | } | ||
81 | |||
82 | /* remaining subframes */ | ||
83 | for( i = 1; i < psEncC->nb_subfr; i++ ) { | ||
84 | silk_assert( psIndices->GainsIndices[ i ] >= 0 && psIndices->GainsIndices[ i ] < MAX_DELTA_GAIN_QUANT - MIN_DELTA_GAIN_QUANT + 1 ); | ||
85 | ec_enc_icdf( psRangeEnc, psIndices->GainsIndices[ i ], silk_delta_gain_iCDF, 8 ); | ||
86 | } | ||
87 | |||
88 | /****************/ | ||
89 | /* Encode NLSFs */ | ||
90 | /****************/ | ||
91 | ec_enc_icdf( psRangeEnc, psIndices->NLSFIndices[ 0 ], &psEncC->psNLSF_CB->CB1_iCDF[ ( psIndices->signalType >> 1 ) * psEncC->psNLSF_CB->nVectors ], 8 ); | ||
92 | silk_NLSF_unpack( ec_ix, pred_Q8, psEncC->psNLSF_CB, psIndices->NLSFIndices[ 0 ] ); | ||
93 | celt_assert( psEncC->psNLSF_CB->order == psEncC->predictLPCOrder ); | ||
94 | for( i = 0; i < psEncC->psNLSF_CB->order; i++ ) { | ||
95 | if( psIndices->NLSFIndices[ i+1 ] >= NLSF_QUANT_MAX_AMPLITUDE ) { | ||
96 | ec_enc_icdf( psRangeEnc, 2 * NLSF_QUANT_MAX_AMPLITUDE, &psEncC->psNLSF_CB->ec_iCDF[ ec_ix[ i ] ], 8 ); | ||
97 | ec_enc_icdf( psRangeEnc, psIndices->NLSFIndices[ i+1 ] - NLSF_QUANT_MAX_AMPLITUDE, silk_NLSF_EXT_iCDF, 8 ); | ||
98 | } else if( psIndices->NLSFIndices[ i+1 ] <= -NLSF_QUANT_MAX_AMPLITUDE ) { | ||
99 | ec_enc_icdf( psRangeEnc, 0, &psEncC->psNLSF_CB->ec_iCDF[ ec_ix[ i ] ], 8 ); | ||
100 | ec_enc_icdf( psRangeEnc, -psIndices->NLSFIndices[ i+1 ] - NLSF_QUANT_MAX_AMPLITUDE, silk_NLSF_EXT_iCDF, 8 ); | ||
101 | } else { | ||
102 | ec_enc_icdf( psRangeEnc, psIndices->NLSFIndices[ i+1 ] + NLSF_QUANT_MAX_AMPLITUDE, &psEncC->psNLSF_CB->ec_iCDF[ ec_ix[ i ] ], 8 ); | ||
103 | } | ||
104 | } | ||
105 | |||
106 | /* Encode NLSF interpolation factor */ | ||
107 | if( psEncC->nb_subfr == MAX_NB_SUBFR ) { | ||
108 | silk_assert( psIndices->NLSFInterpCoef_Q2 >= 0 && psIndices->NLSFInterpCoef_Q2 < 5 ); | ||
109 | ec_enc_icdf( psRangeEnc, psIndices->NLSFInterpCoef_Q2, silk_NLSF_interpolation_factor_iCDF, 8 ); | ||
110 | } | ||
111 | |||
112 | if( psIndices->signalType == TYPE_VOICED ) | ||
113 | { | ||
114 | /*********************/ | ||
115 | /* Encode pitch lags */ | ||
116 | /*********************/ | ||
117 | /* lag index */ | ||
118 | encode_absolute_lagIndex = 1; | ||
119 | if( condCoding == CODE_CONDITIONALLY && psEncC->ec_prevSignalType == TYPE_VOICED ) { | ||
120 | /* Delta Encoding */ | ||
121 | delta_lagIndex = psIndices->lagIndex - psEncC->ec_prevLagIndex; | ||
122 | if( delta_lagIndex < -8 || delta_lagIndex > 11 ) { | ||
123 | delta_lagIndex = 0; | ||
124 | } else { | ||
125 | delta_lagIndex = delta_lagIndex + 9; | ||
126 | encode_absolute_lagIndex = 0; /* Only use delta */ | ||
127 | } | ||
128 | silk_assert( delta_lagIndex >= 0 && delta_lagIndex < 21 ); | ||
129 | ec_enc_icdf( psRangeEnc, delta_lagIndex, silk_pitch_delta_iCDF, 8 ); | ||
130 | } | ||
131 | if( encode_absolute_lagIndex ) { | ||
132 | /* Absolute encoding */ | ||
133 | opus_int32 pitch_high_bits, pitch_low_bits; | ||
134 | pitch_high_bits = silk_DIV32_16( psIndices->lagIndex, silk_RSHIFT( psEncC->fs_kHz, 1 ) ); | ||
135 | pitch_low_bits = psIndices->lagIndex - silk_SMULBB( pitch_high_bits, silk_RSHIFT( psEncC->fs_kHz, 1 ) ); | ||
136 | silk_assert( pitch_low_bits < psEncC->fs_kHz / 2 ); | ||
137 | silk_assert( pitch_high_bits < 32 ); | ||
138 | ec_enc_icdf( psRangeEnc, pitch_high_bits, silk_pitch_lag_iCDF, 8 ); | ||
139 | ec_enc_icdf( psRangeEnc, pitch_low_bits, psEncC->pitch_lag_low_bits_iCDF, 8 ); | ||
140 | } | ||
141 | psEncC->ec_prevLagIndex = psIndices->lagIndex; | ||
142 | |||
143 | /* Countour index */ | ||
144 | silk_assert( psIndices->contourIndex >= 0 ); | ||
145 | silk_assert( ( psIndices->contourIndex < 34 && psEncC->fs_kHz > 8 && psEncC->nb_subfr == 4 ) || | ||
146 | ( psIndices->contourIndex < 11 && psEncC->fs_kHz == 8 && psEncC->nb_subfr == 4 ) || | ||
147 | ( psIndices->contourIndex < 12 && psEncC->fs_kHz > 8 && psEncC->nb_subfr == 2 ) || | ||
148 | ( psIndices->contourIndex < 3 && psEncC->fs_kHz == 8 && psEncC->nb_subfr == 2 ) ); | ||
149 | ec_enc_icdf( psRangeEnc, psIndices->contourIndex, psEncC->pitch_contour_iCDF, 8 ); | ||
150 | |||
151 | /********************/ | ||
152 | /* Encode LTP gains */ | ||
153 | /********************/ | ||
154 | /* PERIndex value */ | ||
155 | silk_assert( psIndices->PERIndex >= 0 && psIndices->PERIndex < 3 ); | ||
156 | ec_enc_icdf( psRangeEnc, psIndices->PERIndex, silk_LTP_per_index_iCDF, 8 ); | ||
157 | |||
158 | /* Codebook Indices */ | ||
159 | for( k = 0; k < psEncC->nb_subfr; k++ ) { | ||
160 | silk_assert( psIndices->LTPIndex[ k ] >= 0 && psIndices->LTPIndex[ k ] < ( 8 << psIndices->PERIndex ) ); | ||
161 | ec_enc_icdf( psRangeEnc, psIndices->LTPIndex[ k ], silk_LTP_gain_iCDF_ptrs[ psIndices->PERIndex ], 8 ); | ||
162 | } | ||
163 | |||
164 | /**********************/ | ||
165 | /* Encode LTP scaling */ | ||
166 | /**********************/ | ||
167 | if( condCoding == CODE_INDEPENDENTLY ) { | ||
168 | silk_assert( psIndices->LTP_scaleIndex >= 0 && psIndices->LTP_scaleIndex < 3 ); | ||
169 | ec_enc_icdf( psRangeEnc, psIndices->LTP_scaleIndex, silk_LTPscale_iCDF, 8 ); | ||
170 | } | ||
171 | silk_assert( !condCoding || psIndices->LTP_scaleIndex == 0 ); | ||
172 | } | ||
173 | |||
174 | psEncC->ec_prevSignalType = psIndices->signalType; | ||
175 | |||
176 | /***************/ | ||
177 | /* Encode seed */ | ||
178 | /***************/ | ||
179 | silk_assert( psIndices->Seed >= 0 && psIndices->Seed < 4 ); | ||
180 | ec_enc_icdf( psRangeEnc, psIndices->Seed, silk_uniform4_iCDF, 8 ); | ||
181 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/encode_pulses.c b/lib/rbcodec/codecs/libopus/silk/encode_pulses.c new file mode 100644 index 0000000000..8a1999138b --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/encode_pulses.c | |||
@@ -0,0 +1,206 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main.h" | ||
33 | #include "stack_alloc.h" | ||
34 | |||
35 | /*********************************************/ | ||
36 | /* Encode quantization indices of excitation */ | ||
37 | /*********************************************/ | ||
38 | |||
39 | static OPUS_INLINE opus_int combine_and_check( /* return ok */ | ||
40 | opus_int *pulses_comb, /* O */ | ||
41 | const opus_int *pulses_in, /* I */ | ||
42 | opus_int max_pulses, /* I max value for sum of pulses */ | ||
43 | opus_int len /* I number of output values */ | ||
44 | ) | ||
45 | { | ||
46 | opus_int k, sum; | ||
47 | |||
48 | for( k = 0; k < len; k++ ) { | ||
49 | sum = pulses_in[ 2 * k ] + pulses_in[ 2 * k + 1 ]; | ||
50 | if( sum > max_pulses ) { | ||
51 | return 1; | ||
52 | } | ||
53 | pulses_comb[ k ] = sum; | ||
54 | } | ||
55 | |||
56 | return 0; | ||
57 | } | ||
58 | |||
59 | /* Encode quantization indices of excitation */ | ||
60 | void silk_encode_pulses( | ||
61 | ec_enc *psRangeEnc, /* I/O compressor data structure */ | ||
62 | const opus_int signalType, /* I Signal type */ | ||
63 | const opus_int quantOffsetType, /* I quantOffsetType */ | ||
64 | opus_int8 pulses[], /* I quantization indices */ | ||
65 | const opus_int frame_length /* I Frame length */ | ||
66 | ) | ||
67 | { | ||
68 | opus_int i, k, j, iter, bit, nLS, scale_down, RateLevelIndex = 0; | ||
69 | opus_int32 abs_q, minSumBits_Q5, sumBits_Q5; | ||
70 | VARDECL( opus_int, abs_pulses ); | ||
71 | VARDECL( opus_int, sum_pulses ); | ||
72 | VARDECL( opus_int, nRshifts ); | ||
73 | opus_int pulses_comb[ 8 ]; | ||
74 | opus_int *abs_pulses_ptr; | ||
75 | const opus_int8 *pulses_ptr; | ||
76 | const opus_uint8 *cdf_ptr; | ||
77 | const opus_uint8 *nBits_ptr; | ||
78 | SAVE_STACK; | ||
79 | |||
80 | silk_memset( pulses_comb, 0, 8 * sizeof( opus_int ) ); /* Fixing Valgrind reported problem*/ | ||
81 | |||
82 | /****************************/ | ||
83 | /* Prepare for shell coding */ | ||
84 | /****************************/ | ||
85 | /* Calculate number of shell blocks */ | ||
86 | silk_assert( 1 << LOG2_SHELL_CODEC_FRAME_LENGTH == SHELL_CODEC_FRAME_LENGTH ); | ||
87 | iter = silk_RSHIFT( frame_length, LOG2_SHELL_CODEC_FRAME_LENGTH ); | ||
88 | if( iter * SHELL_CODEC_FRAME_LENGTH < frame_length ) { | ||
89 | celt_assert( frame_length == 12 * 10 ); /* Make sure only happens for 10 ms @ 12 kHz */ | ||
90 | iter++; | ||
91 | silk_memset( &pulses[ frame_length ], 0, SHELL_CODEC_FRAME_LENGTH * sizeof(opus_int8)); | ||
92 | } | ||
93 | |||
94 | /* Take the absolute value of the pulses */ | ||
95 | ALLOC( abs_pulses, iter * SHELL_CODEC_FRAME_LENGTH, opus_int ); | ||
96 | silk_assert( !( SHELL_CODEC_FRAME_LENGTH & 3 ) ); | ||
97 | for( i = 0; i < iter * SHELL_CODEC_FRAME_LENGTH; i+=4 ) { | ||
98 | abs_pulses[i+0] = ( opus_int )silk_abs( pulses[ i + 0 ] ); | ||
99 | abs_pulses[i+1] = ( opus_int )silk_abs( pulses[ i + 1 ] ); | ||
100 | abs_pulses[i+2] = ( opus_int )silk_abs( pulses[ i + 2 ] ); | ||
101 | abs_pulses[i+3] = ( opus_int )silk_abs( pulses[ i + 3 ] ); | ||
102 | } | ||
103 | |||
104 | /* Calc sum pulses per shell code frame */ | ||
105 | ALLOC( sum_pulses, iter, opus_int ); | ||
106 | ALLOC( nRshifts, iter, opus_int ); | ||
107 | abs_pulses_ptr = abs_pulses; | ||
108 | for( i = 0; i < iter; i++ ) { | ||
109 | nRshifts[ i ] = 0; | ||
110 | |||
111 | while( 1 ) { | ||
112 | /* 1+1 -> 2 */ | ||
113 | scale_down = combine_and_check( pulses_comb, abs_pulses_ptr, silk_max_pulses_table[ 0 ], 8 ); | ||
114 | /* 2+2 -> 4 */ | ||
115 | scale_down += combine_and_check( pulses_comb, pulses_comb, silk_max_pulses_table[ 1 ], 4 ); | ||
116 | /* 4+4 -> 8 */ | ||
117 | scale_down += combine_and_check( pulses_comb, pulses_comb, silk_max_pulses_table[ 2 ], 2 ); | ||
118 | /* 8+8 -> 16 */ | ||
119 | scale_down += combine_and_check( &sum_pulses[ i ], pulses_comb, silk_max_pulses_table[ 3 ], 1 ); | ||
120 | |||
121 | if( scale_down ) { | ||
122 | /* We need to downscale the quantization signal */ | ||
123 | nRshifts[ i ]++; | ||
124 | for( k = 0; k < SHELL_CODEC_FRAME_LENGTH; k++ ) { | ||
125 | abs_pulses_ptr[ k ] = silk_RSHIFT( abs_pulses_ptr[ k ], 1 ); | ||
126 | } | ||
127 | } else { | ||
128 | /* Jump out of while(1) loop and go to next shell coding frame */ | ||
129 | break; | ||
130 | } | ||
131 | } | ||
132 | abs_pulses_ptr += SHELL_CODEC_FRAME_LENGTH; | ||
133 | } | ||
134 | |||
135 | /**************/ | ||
136 | /* Rate level */ | ||
137 | /**************/ | ||
138 | /* find rate level that leads to fewest bits for coding of pulses per block info */ | ||
139 | minSumBits_Q5 = silk_int32_MAX; | ||
140 | for( k = 0; k < N_RATE_LEVELS - 1; k++ ) { | ||
141 | nBits_ptr = silk_pulses_per_block_BITS_Q5[ k ]; | ||
142 | sumBits_Q5 = silk_rate_levels_BITS_Q5[ signalType >> 1 ][ k ]; | ||
143 | for( i = 0; i < iter; i++ ) { | ||
144 | if( nRshifts[ i ] > 0 ) { | ||
145 | sumBits_Q5 += nBits_ptr[ SILK_MAX_PULSES + 1 ]; | ||
146 | } else { | ||
147 | sumBits_Q5 += nBits_ptr[ sum_pulses[ i ] ]; | ||
148 | } | ||
149 | } | ||
150 | if( sumBits_Q5 < minSumBits_Q5 ) { | ||
151 | minSumBits_Q5 = sumBits_Q5; | ||
152 | RateLevelIndex = k; | ||
153 | } | ||
154 | } | ||
155 | ec_enc_icdf( psRangeEnc, RateLevelIndex, silk_rate_levels_iCDF[ signalType >> 1 ], 8 ); | ||
156 | |||
157 | /***************************************************/ | ||
158 | /* Sum-Weighted-Pulses Encoding */ | ||
159 | /***************************************************/ | ||
160 | cdf_ptr = silk_pulses_per_block_iCDF[ RateLevelIndex ]; | ||
161 | for( i = 0; i < iter; i++ ) { | ||
162 | if( nRshifts[ i ] == 0 ) { | ||
163 | ec_enc_icdf( psRangeEnc, sum_pulses[ i ], cdf_ptr, 8 ); | ||
164 | } else { | ||
165 | ec_enc_icdf( psRangeEnc, SILK_MAX_PULSES + 1, cdf_ptr, 8 ); | ||
166 | for( k = 0; k < nRshifts[ i ] - 1; k++ ) { | ||
167 | ec_enc_icdf( psRangeEnc, SILK_MAX_PULSES + 1, silk_pulses_per_block_iCDF[ N_RATE_LEVELS - 1 ], 8 ); | ||
168 | } | ||
169 | ec_enc_icdf( psRangeEnc, sum_pulses[ i ], silk_pulses_per_block_iCDF[ N_RATE_LEVELS - 1 ], 8 ); | ||
170 | } | ||
171 | } | ||
172 | |||
173 | /******************/ | ||
174 | /* Shell Encoding */ | ||
175 | /******************/ | ||
176 | for( i = 0; i < iter; i++ ) { | ||
177 | if( sum_pulses[ i ] > 0 ) { | ||
178 | silk_shell_encoder( psRangeEnc, &abs_pulses[ i * SHELL_CODEC_FRAME_LENGTH ] ); | ||
179 | } | ||
180 | } | ||
181 | |||
182 | /****************/ | ||
183 | /* LSB Encoding */ | ||
184 | /****************/ | ||
185 | for( i = 0; i < iter; i++ ) { | ||
186 | if( nRshifts[ i ] > 0 ) { | ||
187 | pulses_ptr = &pulses[ i * SHELL_CODEC_FRAME_LENGTH ]; | ||
188 | nLS = nRshifts[ i ] - 1; | ||
189 | for( k = 0; k < SHELL_CODEC_FRAME_LENGTH; k++ ) { | ||
190 | abs_q = (opus_int8)silk_abs( pulses_ptr[ k ] ); | ||
191 | for( j = nLS; j > 0; j-- ) { | ||
192 | bit = silk_RSHIFT( abs_q, j ) & 1; | ||
193 | ec_enc_icdf( psRangeEnc, bit, silk_lsb_iCDF, 8 ); | ||
194 | } | ||
195 | bit = abs_q & 1; | ||
196 | ec_enc_icdf( psRangeEnc, bit, silk_lsb_iCDF, 8 ); | ||
197 | } | ||
198 | } | ||
199 | } | ||
200 | |||
201 | /****************/ | ||
202 | /* Encode signs */ | ||
203 | /****************/ | ||
204 | silk_encode_signs( psRangeEnc, pulses, frame_length, signalType, quantOffsetType, sum_pulses ); | ||
205 | RESTORE_STACK; | ||
206 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/LTP_analysis_filter_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/LTP_analysis_filter_FIX.c new file mode 100644 index 0000000000..5574e7069f --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/fixed/LTP_analysis_filter_FIX.c | |||
@@ -0,0 +1,90 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main_FIX.h" | ||
33 | |||
34 | void silk_LTP_analysis_filter_FIX( | ||
35 | opus_int16 *LTP_res, /* O LTP residual signal of length MAX_NB_SUBFR * ( pre_length + subfr_length ) */ | ||
36 | const opus_int16 *x, /* I Pointer to input signal with at least max( pitchL ) preceding samples */ | ||
37 | const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],/* I LTP_ORDER LTP coefficients for each MAX_NB_SUBFR subframe */ | ||
38 | const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag, one for each subframe */ | ||
39 | const opus_int32 invGains_Q16[ MAX_NB_SUBFR ], /* I Inverse quantization gains, one for each subframe */ | ||
40 | const opus_int subfr_length, /* I Length of each subframe */ | ||
41 | const opus_int nb_subfr, /* I Number of subframes */ | ||
42 | const opus_int pre_length /* I Length of the preceding samples starting at &x[0] for each subframe */ | ||
43 | ) | ||
44 | { | ||
45 | const opus_int16 *x_ptr, *x_lag_ptr; | ||
46 | opus_int16 Btmp_Q14[ LTP_ORDER ]; | ||
47 | opus_int16 *LTP_res_ptr; | ||
48 | opus_int k, i; | ||
49 | opus_int32 LTP_est; | ||
50 | |||
51 | x_ptr = x; | ||
52 | LTP_res_ptr = LTP_res; | ||
53 | for( k = 0; k < nb_subfr; k++ ) { | ||
54 | |||
55 | x_lag_ptr = x_ptr - pitchL[ k ]; | ||
56 | |||
57 | Btmp_Q14[ 0 ] = LTPCoef_Q14[ k * LTP_ORDER ]; | ||
58 | Btmp_Q14[ 1 ] = LTPCoef_Q14[ k * LTP_ORDER + 1 ]; | ||
59 | Btmp_Q14[ 2 ] = LTPCoef_Q14[ k * LTP_ORDER + 2 ]; | ||
60 | Btmp_Q14[ 3 ] = LTPCoef_Q14[ k * LTP_ORDER + 3 ]; | ||
61 | Btmp_Q14[ 4 ] = LTPCoef_Q14[ k * LTP_ORDER + 4 ]; | ||
62 | |||
63 | /* LTP analysis FIR filter */ | ||
64 | for( i = 0; i < subfr_length + pre_length; i++ ) { | ||
65 | LTP_res_ptr[ i ] = x_ptr[ i ]; | ||
66 | |||
67 | /* Long-term prediction */ | ||
68 | LTP_est = silk_SMULBB( x_lag_ptr[ LTP_ORDER / 2 ], Btmp_Q14[ 0 ] ); | ||
69 | LTP_est = silk_SMLABB_ovflw( LTP_est, x_lag_ptr[ 1 ], Btmp_Q14[ 1 ] ); | ||
70 | LTP_est = silk_SMLABB_ovflw( LTP_est, x_lag_ptr[ 0 ], Btmp_Q14[ 2 ] ); | ||
71 | LTP_est = silk_SMLABB_ovflw( LTP_est, x_lag_ptr[ -1 ], Btmp_Q14[ 3 ] ); | ||
72 | LTP_est = silk_SMLABB_ovflw( LTP_est, x_lag_ptr[ -2 ], Btmp_Q14[ 4 ] ); | ||
73 | |||
74 | LTP_est = silk_RSHIFT_ROUND( LTP_est, 14 ); /* round and -> Q0*/ | ||
75 | |||
76 | /* Subtract long-term prediction */ | ||
77 | LTP_res_ptr[ i ] = (opus_int16)silk_SAT16( (opus_int32)x_ptr[ i ] - LTP_est ); | ||
78 | |||
79 | /* Scale residual */ | ||
80 | LTP_res_ptr[ i ] = silk_SMULWB( invGains_Q16[ k ], LTP_res_ptr[ i ] ); | ||
81 | |||
82 | x_lag_ptr++; | ||
83 | } | ||
84 | |||
85 | /* Update pointers */ | ||
86 | LTP_res_ptr += subfr_length + pre_length; | ||
87 | x_ptr += subfr_length; | ||
88 | } | ||
89 | } | ||
90 | |||
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/LTP_scale_ctrl_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/LTP_scale_ctrl_FIX.c new file mode 100644 index 0000000000..3dcedef891 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/fixed/LTP_scale_ctrl_FIX.c | |||
@@ -0,0 +1,53 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main_FIX.h" | ||
33 | |||
34 | /* Calculation of LTP state scaling */ | ||
35 | void silk_LTP_scale_ctrl_FIX( | ||
36 | silk_encoder_state_FIX *psEnc, /* I/O encoder state */ | ||
37 | silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */ | ||
38 | opus_int condCoding /* I The type of conditional coding to use */ | ||
39 | ) | ||
40 | { | ||
41 | opus_int round_loss; | ||
42 | |||
43 | if( condCoding == CODE_INDEPENDENTLY ) { | ||
44 | /* Only scale if first frame in packet */ | ||
45 | round_loss = psEnc->sCmn.PacketLoss_perc + psEnc->sCmn.nFramesPerPacket; | ||
46 | psEnc->sCmn.indices.LTP_scaleIndex = (opus_int8)silk_LIMIT( | ||
47 | silk_SMULWB( silk_SMULBB( round_loss, psEncCtrl->LTPredCodGain_Q7 ), SILK_FIX_CONST( 0.1, 9 ) ), 0, 2 ); | ||
48 | } else { | ||
49 | /* Default is minimum scaling */ | ||
50 | psEnc->sCmn.indices.LTP_scaleIndex = 0; | ||
51 | } | ||
52 | psEncCtrl->LTP_scale_Q14 = silk_LTPScales_table_Q14[ psEnc->sCmn.indices.LTP_scaleIndex ]; | ||
53 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/apply_sine_window_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/apply_sine_window_FIX.c new file mode 100644 index 0000000000..03e088a6de --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/fixed/apply_sine_window_FIX.c | |||
@@ -0,0 +1,101 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "SigProc_FIX.h" | ||
33 | |||
34 | /* Apply sine window to signal vector. */ | ||
35 | /* Window types: */ | ||
36 | /* 1 -> sine window from 0 to pi/2 */ | ||
37 | /* 2 -> sine window from pi/2 to pi */ | ||
38 | /* Every other sample is linearly interpolated, for speed. */ | ||
39 | /* Window length must be between 16 and 120 (incl) and a multiple of 4. */ | ||
40 | |||
41 | /* Matlab code for table: | ||
42 | for k=16:9*4:16+2*9*4, fprintf(' %7.d,', -round(65536*pi ./ (k:4:k+8*4))); fprintf('\n'); end | ||
43 | */ | ||
44 | static const opus_int16 freq_table_Q16[ 27 ] = { | ||
45 | 12111, 9804, 8235, 7100, 6239, 5565, 5022, 4575, 4202, | ||
46 | 3885, 3612, 3375, 3167, 2984, 2820, 2674, 2542, 2422, | ||
47 | 2313, 2214, 2123, 2038, 1961, 1889, 1822, 1760, 1702, | ||
48 | }; | ||
49 | |||
50 | void silk_apply_sine_window( | ||
51 | opus_int16 px_win[], /* O Pointer to windowed signal */ | ||
52 | const opus_int16 px[], /* I Pointer to input signal */ | ||
53 | const opus_int win_type, /* I Selects a window type */ | ||
54 | const opus_int length /* I Window length, multiple of 4 */ | ||
55 | ) | ||
56 | { | ||
57 | opus_int k, f_Q16, c_Q16; | ||
58 | opus_int32 S0_Q16, S1_Q16; | ||
59 | |||
60 | celt_assert( win_type == 1 || win_type == 2 ); | ||
61 | |||
62 | /* Length must be in a range from 16 to 120 and a multiple of 4 */ | ||
63 | celt_assert( length >= 16 && length <= 120 ); | ||
64 | celt_assert( ( length & 3 ) == 0 ); | ||
65 | |||
66 | /* Frequency */ | ||
67 | k = ( length >> 2 ) - 4; | ||
68 | celt_assert( k >= 0 && k <= 26 ); | ||
69 | f_Q16 = (opus_int)freq_table_Q16[ k ]; | ||
70 | |||
71 | /* Factor used for cosine approximation */ | ||
72 | c_Q16 = silk_SMULWB( (opus_int32)f_Q16, -f_Q16 ); | ||
73 | silk_assert( c_Q16 >= -32768 ); | ||
74 | |||
75 | /* initialize state */ | ||
76 | if( win_type == 1 ) { | ||
77 | /* start from 0 */ | ||
78 | S0_Q16 = 0; | ||
79 | /* approximation of sin(f) */ | ||
80 | S1_Q16 = f_Q16 + silk_RSHIFT( length, 3 ); | ||
81 | } else { | ||
82 | /* start from 1 */ | ||
83 | S0_Q16 = ( (opus_int32)1 << 16 ); | ||
84 | /* approximation of cos(f) */ | ||
85 | S1_Q16 = ( (opus_int32)1 << 16 ) + silk_RSHIFT( c_Q16, 1 ) + silk_RSHIFT( length, 4 ); | ||
86 | } | ||
87 | |||
88 | /* Uses the recursive equation: sin(n*f) = 2 * cos(f) * sin((n-1)*f) - sin((n-2)*f) */ | ||
89 | /* 4 samples at a time */ | ||
90 | for( k = 0; k < length; k += 4 ) { | ||
91 | px_win[ k ] = (opus_int16)silk_SMULWB( silk_RSHIFT( S0_Q16 + S1_Q16, 1 ), px[ k ] ); | ||
92 | px_win[ k + 1 ] = (opus_int16)silk_SMULWB( S1_Q16, px[ k + 1] ); | ||
93 | S0_Q16 = silk_SMULWB( S1_Q16, c_Q16 ) + silk_LSHIFT( S1_Q16, 1 ) - S0_Q16 + 1; | ||
94 | S0_Q16 = silk_min( S0_Q16, ( (opus_int32)1 << 16 ) ); | ||
95 | |||
96 | px_win[ k + 2 ] = (opus_int16)silk_SMULWB( silk_RSHIFT( S0_Q16 + S1_Q16, 1 ), px[ k + 2] ); | ||
97 | px_win[ k + 3 ] = (opus_int16)silk_SMULWB( S0_Q16, px[ k + 3 ] ); | ||
98 | S1_Q16 = silk_SMULWB( S0_Q16, c_Q16 ) + silk_LSHIFT( S0_Q16, 1 ) - S1_Q16; | ||
99 | S1_Q16 = silk_min( S1_Q16, ( (opus_int32)1 << 16 ) ); | ||
100 | } | ||
101 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/arm/warped_autocorrelation_FIX_arm.h b/lib/rbcodec/codecs/libopus/silk/fixed/arm/warped_autocorrelation_FIX_arm.h new file mode 100644 index 0000000000..1992e43288 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/fixed/arm/warped_autocorrelation_FIX_arm.h | |||
@@ -0,0 +1,68 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2017 Google Inc. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifndef SILK_WARPED_AUTOCORRELATION_FIX_ARM_H | ||
29 | # define SILK_WARPED_AUTOCORRELATION_FIX_ARM_H | ||
30 | |||
31 | # include "celt/arm/armcpu.h" | ||
32 | |||
33 | # if defined(FIXED_POINT) | ||
34 | |||
35 | # if defined(OPUS_ARM_MAY_HAVE_NEON_INTR) | ||
36 | void silk_warped_autocorrelation_FIX_neon( | ||
37 | opus_int32 *corr, /* O Result [order + 1] */ | ||
38 | opus_int *scale, /* O Scaling of the correlation vector */ | ||
39 | const opus_int16 *input, /* I Input data to correlate */ | ||
40 | const opus_int warping_Q16, /* I Warping coefficient */ | ||
41 | const opus_int length, /* I Length of input */ | ||
42 | const opus_int order /* I Correlation order (even) */ | ||
43 | ); | ||
44 | |||
45 | # if !defined(OPUS_HAVE_RTCD) && defined(OPUS_ARM_PRESUME_NEON) | ||
46 | # define OVERRIDE_silk_warped_autocorrelation_FIX (1) | ||
47 | # define silk_warped_autocorrelation_FIX(corr, scale, input, warping_Q16, length, order, arch) \ | ||
48 | ((void)(arch), PRESUME_NEON(silk_warped_autocorrelation_FIX)(corr, scale, input, warping_Q16, length, order)) | ||
49 | # endif | ||
50 | # endif | ||
51 | |||
52 | # if !defined(OVERRIDE_silk_warped_autocorrelation_FIX) | ||
53 | /*Is run-time CPU detection enabled on this platform?*/ | ||
54 | # if defined(OPUS_HAVE_RTCD) && (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR)) | ||
55 | extern void (*const SILK_WARPED_AUTOCORRELATION_FIX_IMPL[OPUS_ARCHMASK+1])(opus_int32*, opus_int*, const opus_int16*, const opus_int, const opus_int, const opus_int); | ||
56 | # define OVERRIDE_silk_warped_autocorrelation_FIX (1) | ||
57 | # define silk_warped_autocorrelation_FIX(corr, scale, input, warping_Q16, length, order, arch) \ | ||
58 | ((*SILK_WARPED_AUTOCORRELATION_FIX_IMPL[(arch)&OPUS_ARCHMASK])(corr, scale, input, warping_Q16, length, order)) | ||
59 | # elif defined(OPUS_ARM_PRESUME_NEON_INTR) | ||
60 | # define OVERRIDE_silk_warped_autocorrelation_FIX (1) | ||
61 | # define silk_warped_autocorrelation_FIX(corr, scale, input, warping_Q16, length, order, arch) \ | ||
62 | ((void)(arch), silk_warped_autocorrelation_FIX_neon(corr, scale, input, warping_Q16, length, order)) | ||
63 | # endif | ||
64 | # endif | ||
65 | |||
66 | # endif /* end FIXED_POINT */ | ||
67 | |||
68 | #endif /* end SILK_WARPED_AUTOCORRELATION_FIX_ARM_H */ | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/arm/warped_autocorrelation_FIX_neon_intr.c b/lib/rbcodec/codecs/libopus/silk/fixed/arm/warped_autocorrelation_FIX_neon_intr.c new file mode 100644 index 0000000000..00a70cb51f --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/fixed/arm/warped_autocorrelation_FIX_neon_intr.c | |||
@@ -0,0 +1,260 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2017 Google Inc., Jean-Marc Valin | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include <arm_neon.h> | ||
33 | #ifdef OPUS_CHECK_ASM | ||
34 | # include <string.h> | ||
35 | #endif | ||
36 | #include "stack_alloc.h" | ||
37 | #include "main_FIX.h" | ||
38 | |||
39 | static OPUS_INLINE void calc_corr( const opus_int32 *const input_QS, opus_int64 *const corr_QC, const opus_int offset, const int32x4_t state_QS_s32x4 ) | ||
40 | { | ||
41 | int64x2_t corr_QC_s64x2[ 2 ], t_s64x2[ 2 ]; | ||
42 | const int32x4_t input_QS_s32x4 = vld1q_s32( input_QS + offset ); | ||
43 | corr_QC_s64x2[ 0 ] = vld1q_s64( corr_QC + offset + 0 ); | ||
44 | corr_QC_s64x2[ 1 ] = vld1q_s64( corr_QC + offset + 2 ); | ||
45 | t_s64x2[ 0 ] = vmull_s32( vget_low_s32( state_QS_s32x4 ), vget_low_s32( input_QS_s32x4 ) ); | ||
46 | t_s64x2[ 1 ] = vmull_s32( vget_high_s32( state_QS_s32x4 ), vget_high_s32( input_QS_s32x4 ) ); | ||
47 | corr_QC_s64x2[ 0 ] = vsraq_n_s64( corr_QC_s64x2[ 0 ], t_s64x2[ 0 ], 2 * QS - QC ); | ||
48 | corr_QC_s64x2[ 1 ] = vsraq_n_s64( corr_QC_s64x2[ 1 ], t_s64x2[ 1 ], 2 * QS - QC ); | ||
49 | vst1q_s64( corr_QC + offset + 0, corr_QC_s64x2[ 0 ] ); | ||
50 | vst1q_s64( corr_QC + offset + 2, corr_QC_s64x2[ 1 ] ); | ||
51 | } | ||
52 | |||
53 | static OPUS_INLINE int32x4_t calc_state( const int32x4_t state_QS0_s32x4, const int32x4_t state_QS0_1_s32x4, const int32x4_t state_QS1_1_s32x4, const int32x4_t warping_Q16_s32x4 ) | ||
54 | { | ||
55 | int32x4_t t_s32x4 = vsubq_s32( state_QS0_s32x4, state_QS0_1_s32x4 ); | ||
56 | t_s32x4 = vqdmulhq_s32( t_s32x4, warping_Q16_s32x4 ); | ||
57 | return vaddq_s32( state_QS1_1_s32x4, t_s32x4 ); | ||
58 | } | ||
59 | |||
60 | void silk_warped_autocorrelation_FIX_neon( | ||
61 | opus_int32 *corr, /* O Result [order + 1] */ | ||
62 | opus_int *scale, /* O Scaling of the correlation vector */ | ||
63 | const opus_int16 *input, /* I Input data to correlate */ | ||
64 | const opus_int warping_Q16, /* I Warping coefficient */ | ||
65 | const opus_int length, /* I Length of input */ | ||
66 | const opus_int order /* I Correlation order (even) */ | ||
67 | ) | ||
68 | { | ||
69 | if( ( MAX_SHAPE_LPC_ORDER > 24 ) || ( order < 6 ) ) { | ||
70 | silk_warped_autocorrelation_FIX_c( corr, scale, input, warping_Q16, length, order ); | ||
71 | } else { | ||
72 | opus_int n, i, lsh; | ||
73 | opus_int64 corr_QC[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 }; /* In reverse order */ | ||
74 | opus_int64 corr_QC_orderT; | ||
75 | int64x2_t lsh_s64x2; | ||
76 | const opus_int orderT = ( order + 3 ) & ~3; | ||
77 | opus_int64 *corr_QCT; | ||
78 | opus_int32 *input_QS; | ||
79 | VARDECL( opus_int32, input_QST ); | ||
80 | VARDECL( opus_int32, state ); | ||
81 | SAVE_STACK; | ||
82 | |||
83 | /* Order must be even */ | ||
84 | silk_assert( ( order & 1 ) == 0 ); | ||
85 | silk_assert( 2 * QS - QC >= 0 ); | ||
86 | |||
87 | ALLOC( input_QST, length + 2 * MAX_SHAPE_LPC_ORDER, opus_int32 ); | ||
88 | |||
89 | input_QS = input_QST; | ||
90 | /* input_QS has zero paddings in the beginning and end. */ | ||
91 | vst1q_s32( input_QS, vdupq_n_s32( 0 ) ); | ||
92 | input_QS += 4; | ||
93 | vst1q_s32( input_QS, vdupq_n_s32( 0 ) ); | ||
94 | input_QS += 4; | ||
95 | vst1q_s32( input_QS, vdupq_n_s32( 0 ) ); | ||
96 | input_QS += 4; | ||
97 | vst1q_s32( input_QS, vdupq_n_s32( 0 ) ); | ||
98 | input_QS += 4; | ||
99 | vst1q_s32( input_QS, vdupq_n_s32( 0 ) ); | ||
100 | input_QS += 4; | ||
101 | vst1q_s32( input_QS, vdupq_n_s32( 0 ) ); | ||
102 | input_QS += 4; | ||
103 | |||
104 | /* Loop over samples */ | ||
105 | for( n = 0; n < length - 7; n += 8, input_QS += 8 ) { | ||
106 | const int16x8_t t0_s16x4 = vld1q_s16( input + n ); | ||
107 | vst1q_s32( input_QS + 0, vshll_n_s16( vget_low_s16( t0_s16x4 ), QS ) ); | ||
108 | vst1q_s32( input_QS + 4, vshll_n_s16( vget_high_s16( t0_s16x4 ), QS ) ); | ||
109 | } | ||
110 | for( ; n < length; n++, input_QS++ ) { | ||
111 | input_QS[ 0 ] = silk_LSHIFT32( (opus_int32)input[ n ], QS ); | ||
112 | } | ||
113 | vst1q_s32( input_QS, vdupq_n_s32( 0 ) ); | ||
114 | input_QS += 4; | ||
115 | vst1q_s32( input_QS, vdupq_n_s32( 0 ) ); | ||
116 | input_QS += 4; | ||
117 | vst1q_s32( input_QS, vdupq_n_s32( 0 ) ); | ||
118 | input_QS += 4; | ||
119 | vst1q_s32( input_QS, vdupq_n_s32( 0 ) ); | ||
120 | input_QS += 4; | ||
121 | vst1q_s32( input_QS, vdupq_n_s32( 0 ) ); | ||
122 | input_QS += 4; | ||
123 | vst1q_s32( input_QS, vdupq_n_s32( 0 ) ); | ||
124 | input_QS = input_QST + MAX_SHAPE_LPC_ORDER - orderT; | ||
125 | |||
126 | /* The following loop runs ( length + order ) times, with ( order ) extra epilogues. */ | ||
127 | /* The zero paddings in input_QS guarantee corr_QC's correctness even with the extra epilogues. */ | ||
128 | /* The values of state_QS will be polluted by the extra epilogues, however they are temporary values. */ | ||
129 | |||
130 | /* Keep the C code here to help understand the intrinsics optimization. */ | ||
131 | /* | ||
132 | { | ||
133 | opus_int32 state_QS[ 2 ][ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 }; | ||
134 | opus_int32 *state_QST[ 3 ]; | ||
135 | state_QST[ 0 ] = state_QS[ 0 ]; | ||
136 | state_QST[ 1 ] = state_QS[ 1 ]; | ||
137 | for( n = 0; n < length + order; n++, input_QS++ ) { | ||
138 | state_QST[ 0 ][ orderT ] = input_QS[ orderT ]; | ||
139 | for( i = 0; i < orderT; i++ ) { | ||
140 | corr_QC[ i ] += silk_RSHIFT64( silk_SMULL( state_QST[ 0 ][ i ], input_QS[ i ] ), 2 * QS - QC ); | ||
141 | state_QST[ 1 ][ i ] = silk_SMLAWB( state_QST[ 1 ][ i + 1 ], state_QST[ 0 ][ i ] - state_QST[ 0 ][ i + 1 ], warping_Q16 ); | ||
142 | } | ||
143 | state_QST[ 2 ] = state_QST[ 0 ]; | ||
144 | state_QST[ 0 ] = state_QST[ 1 ]; | ||
145 | state_QST[ 1 ] = state_QST[ 2 ]; | ||
146 | } | ||
147 | } | ||
148 | */ | ||
149 | |||
150 | { | ||
151 | const int32x4_t warping_Q16_s32x4 = vdupq_n_s32( warping_Q16 << 15 ); | ||
152 | const opus_int32 *in = input_QS + orderT; | ||
153 | opus_int o = orderT; | ||
154 | int32x4_t state_QS_s32x4[ 3 ][ 2 ]; | ||
155 | |||
156 | ALLOC( state, length + orderT, opus_int32 ); | ||
157 | state_QS_s32x4[ 2 ][ 1 ] = vdupq_n_s32( 0 ); | ||
158 | |||
159 | /* Calculate 8 taps of all inputs in each loop. */ | ||
160 | do { | ||
161 | state_QS_s32x4[ 0 ][ 0 ] = state_QS_s32x4[ 0 ][ 1 ] = | ||
162 | state_QS_s32x4[ 1 ][ 0 ] = state_QS_s32x4[ 1 ][ 1 ] = vdupq_n_s32( 0 ); | ||
163 | n = 0; | ||
164 | do { | ||
165 | calc_corr( input_QS + n, corr_QC, o - 8, state_QS_s32x4[ 0 ][ 0 ] ); | ||
166 | calc_corr( input_QS + n, corr_QC, o - 4, state_QS_s32x4[ 0 ][ 1 ] ); | ||
167 | state_QS_s32x4[ 2 ][ 1 ] = vld1q_s32( in + n ); | ||
168 | vst1q_lane_s32( state + n, state_QS_s32x4[ 0 ][ 0 ], 0 ); | ||
169 | state_QS_s32x4[ 2 ][ 0 ] = vextq_s32( state_QS_s32x4[ 0 ][ 0 ], state_QS_s32x4[ 0 ][ 1 ], 1 ); | ||
170 | state_QS_s32x4[ 2 ][ 1 ] = vextq_s32( state_QS_s32x4[ 0 ][ 1 ], state_QS_s32x4[ 2 ][ 1 ], 1 ); | ||
171 | state_QS_s32x4[ 0 ][ 0 ] = calc_state( state_QS_s32x4[ 0 ][ 0 ], state_QS_s32x4[ 2 ][ 0 ], state_QS_s32x4[ 1 ][ 0 ], warping_Q16_s32x4 ); | ||
172 | state_QS_s32x4[ 0 ][ 1 ] = calc_state( state_QS_s32x4[ 0 ][ 1 ], state_QS_s32x4[ 2 ][ 1 ], state_QS_s32x4[ 1 ][ 1 ], warping_Q16_s32x4 ); | ||
173 | state_QS_s32x4[ 1 ][ 0 ] = state_QS_s32x4[ 2 ][ 0 ]; | ||
174 | state_QS_s32x4[ 1 ][ 1 ] = state_QS_s32x4[ 2 ][ 1 ]; | ||
175 | } while( ++n < ( length + order ) ); | ||
176 | in = state; | ||
177 | o -= 8; | ||
178 | } while( o > 4 ); | ||
179 | |||
180 | if( o ) { | ||
181 | /* Calculate the last 4 taps of all inputs. */ | ||
182 | opus_int32 *stateT = state; | ||
183 | silk_assert( o == 4 ); | ||
184 | state_QS_s32x4[ 0 ][ 0 ] = state_QS_s32x4[ 1 ][ 0 ] = vdupq_n_s32( 0 ); | ||
185 | n = length + order; | ||
186 | do { | ||
187 | calc_corr( input_QS, corr_QC, 0, state_QS_s32x4[ 0 ][ 0 ] ); | ||
188 | state_QS_s32x4[ 2 ][ 0 ] = vld1q_s32( stateT ); | ||
189 | vst1q_lane_s32( stateT, state_QS_s32x4[ 0 ][ 0 ], 0 ); | ||
190 | state_QS_s32x4[ 2 ][ 0 ] = vextq_s32( state_QS_s32x4[ 0 ][ 0 ], state_QS_s32x4[ 2 ][ 0 ], 1 ); | ||
191 | state_QS_s32x4[ 0 ][ 0 ] = calc_state( state_QS_s32x4[ 0 ][ 0 ], state_QS_s32x4[ 2 ][ 0 ], state_QS_s32x4[ 1 ][ 0 ], warping_Q16_s32x4 ); | ||
192 | state_QS_s32x4[ 1 ][ 0 ] = state_QS_s32x4[ 2 ][ 0 ]; | ||
193 | input_QS++; | ||
194 | stateT++; | ||
195 | } while( --n ); | ||
196 | } | ||
197 | } | ||
198 | |||
199 | { | ||
200 | const opus_int16 *inputT = input; | ||
201 | int32x4_t t_s32x4; | ||
202 | int64x1_t t_s64x1; | ||
203 | int64x2_t t_s64x2 = vdupq_n_s64( 0 ); | ||
204 | for( n = 0; n <= length - 8; n += 8 ) { | ||
205 | int16x8_t input_s16x8 = vld1q_s16( inputT ); | ||
206 | t_s32x4 = vmull_s16( vget_low_s16( input_s16x8 ), vget_low_s16( input_s16x8 ) ); | ||
207 | t_s32x4 = vmlal_s16( t_s32x4, vget_high_s16( input_s16x8 ), vget_high_s16( input_s16x8 ) ); | ||
208 | t_s64x2 = vaddw_s32( t_s64x2, vget_low_s32( t_s32x4 ) ); | ||
209 | t_s64x2 = vaddw_s32( t_s64x2, vget_high_s32( t_s32x4 ) ); | ||
210 | inputT += 8; | ||
211 | } | ||
212 | t_s64x1 = vadd_s64( vget_low_s64( t_s64x2 ), vget_high_s64( t_s64x2 ) ); | ||
213 | corr_QC_orderT = vget_lane_s64( t_s64x1, 0 ); | ||
214 | for( ; n < length; n++ ) { | ||
215 | corr_QC_orderT += silk_SMULL( input[ n ], input[ n ] ); | ||
216 | } | ||
217 | corr_QC_orderT = silk_LSHIFT64( corr_QC_orderT, QC ); | ||
218 | corr_QC[ orderT ] = corr_QC_orderT; | ||
219 | } | ||
220 | |||
221 | corr_QCT = corr_QC + orderT - order; | ||
222 | lsh = silk_CLZ64( corr_QC_orderT ) - 35; | ||
223 | lsh = silk_LIMIT( lsh, -12 - QC, 30 - QC ); | ||
224 | *scale = -( QC + lsh ); | ||
225 | silk_assert( *scale >= -30 && *scale <= 12 ); | ||
226 | lsh_s64x2 = vdupq_n_s64( lsh ); | ||
227 | for( i = 0; i <= order - 3; i += 4 ) { | ||
228 | int32x4_t corr_s32x4; | ||
229 | int64x2_t corr_QC0_s64x2, corr_QC1_s64x2; | ||
230 | corr_QC0_s64x2 = vld1q_s64( corr_QCT + i ); | ||
231 | corr_QC1_s64x2 = vld1q_s64( corr_QCT + i + 2 ); | ||
232 | corr_QC0_s64x2 = vshlq_s64( corr_QC0_s64x2, lsh_s64x2 ); | ||
233 | corr_QC1_s64x2 = vshlq_s64( corr_QC1_s64x2, lsh_s64x2 ); | ||
234 | corr_s32x4 = vcombine_s32( vmovn_s64( corr_QC1_s64x2 ), vmovn_s64( corr_QC0_s64x2 ) ); | ||
235 | corr_s32x4 = vrev64q_s32( corr_s32x4 ); | ||
236 | vst1q_s32( corr + order - i - 3, corr_s32x4 ); | ||
237 | } | ||
238 | if( lsh >= 0 ) { | ||
239 | for( ; i < order + 1; i++ ) { | ||
240 | corr[ order - i ] = (opus_int32)silk_CHECK_FIT32( silk_LSHIFT64( corr_QCT[ i ], lsh ) ); | ||
241 | } | ||
242 | } else { | ||
243 | for( ; i < order + 1; i++ ) { | ||
244 | corr[ order - i ] = (opus_int32)silk_CHECK_FIT32( silk_RSHIFT64( corr_QCT[ i ], -lsh ) ); | ||
245 | } | ||
246 | } | ||
247 | silk_assert( corr_QCT[ order ] >= 0 ); /* If breaking, decrease QC*/ | ||
248 | RESTORE_STACK; | ||
249 | } | ||
250 | |||
251 | #ifdef OPUS_CHECK_ASM | ||
252 | { | ||
253 | opus_int32 corr_c[ MAX_SHAPE_LPC_ORDER + 1 ]; | ||
254 | opus_int scale_c; | ||
255 | silk_warped_autocorrelation_FIX_c( corr_c, &scale_c, input, warping_Q16, length, order ); | ||
256 | silk_assert( !memcmp( corr_c, corr, sizeof( corr_c[ 0 ] ) * ( order + 1 ) ) ); | ||
257 | silk_assert( scale_c == *scale ); | ||
258 | } | ||
259 | #endif | ||
260 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/autocorr_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/autocorr_FIX.c new file mode 100644 index 0000000000..de95c98693 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/fixed/autocorr_FIX.c | |||
@@ -0,0 +1,48 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "SigProc_FIX.h" | ||
33 | #include "celt_lpc.h" | ||
34 | |||
35 | /* Compute autocorrelation */ | ||
36 | void silk_autocorr( | ||
37 | opus_int32 *results, /* O Result (length correlationCount) */ | ||
38 | opus_int *scale, /* O Scaling of the correlation vector */ | ||
39 | const opus_int16 *inputData, /* I Input data to correlate */ | ||
40 | const opus_int inputDataSize, /* I Length of input */ | ||
41 | const opus_int correlationCount, /* I Number of correlation taps to compute */ | ||
42 | int arch /* I Run-time architecture */ | ||
43 | ) | ||
44 | { | ||
45 | opus_int corrCount; | ||
46 | corrCount = silk_min_int( inputDataSize, correlationCount ); | ||
47 | *scale = _celt_autocorr(inputData, results, NULL, 0, corrCount-1, inputDataSize, arch); | ||
48 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/burg_modified_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/burg_modified_FIX.c new file mode 100644 index 0000000000..274d4b28e1 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/fixed/burg_modified_FIX.c | |||
@@ -0,0 +1,280 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "SigProc_FIX.h" | ||
33 | #include "define.h" | ||
34 | #include "tuning_parameters.h" | ||
35 | #include "pitch.h" | ||
36 | |||
37 | #define MAX_FRAME_SIZE 384 /* subfr_length * nb_subfr = ( 0.005 * 16000 + 16 ) * 4 = 384 */ | ||
38 | |||
39 | #define QA 25 | ||
40 | #define N_BITS_HEAD_ROOM 3 | ||
41 | #define MIN_RSHIFTS -16 | ||
42 | #define MAX_RSHIFTS (32 - QA) | ||
43 | |||
44 | /* Compute reflection coefficients from input signal */ | ||
45 | void silk_burg_modified_c( | ||
46 | opus_int32 *res_nrg, /* O Residual energy */ | ||
47 | opus_int *res_nrg_Q, /* O Residual energy Q value */ | ||
48 | opus_int32 A_Q16[], /* O Prediction coefficients (length order) */ | ||
49 | const opus_int16 x[], /* I Input signal, length: nb_subfr * ( D + subfr_length ) */ | ||
50 | const opus_int32 minInvGain_Q30, /* I Inverse of max prediction gain */ | ||
51 | const opus_int subfr_length, /* I Input signal subframe length (incl. D preceding samples) */ | ||
52 | const opus_int nb_subfr, /* I Number of subframes stacked in x */ | ||
53 | const opus_int D, /* I Order */ | ||
54 | int arch /* I Run-time architecture */ | ||
55 | ) | ||
56 | { | ||
57 | opus_int k, n, s, lz, rshifts, reached_max_gain; | ||
58 | opus_int32 C0, num, nrg, rc_Q31, invGain_Q30, Atmp_QA, Atmp1, tmp1, tmp2, x1, x2; | ||
59 | const opus_int16 *x_ptr; | ||
60 | opus_int32 C_first_row[ SILK_MAX_ORDER_LPC ]; | ||
61 | opus_int32 C_last_row[ SILK_MAX_ORDER_LPC ]; | ||
62 | opus_int32 Af_QA[ SILK_MAX_ORDER_LPC ]; | ||
63 | opus_int32 CAf[ SILK_MAX_ORDER_LPC + 1 ]; | ||
64 | opus_int32 CAb[ SILK_MAX_ORDER_LPC + 1 ]; | ||
65 | opus_int32 xcorr[ SILK_MAX_ORDER_LPC ]; | ||
66 | opus_int64 C0_64; | ||
67 | |||
68 | celt_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE ); | ||
69 | |||
70 | /* Compute autocorrelations, added over subframes */ | ||
71 | C0_64 = silk_inner_prod16_aligned_64( x, x, subfr_length*nb_subfr, arch ); | ||
72 | lz = silk_CLZ64(C0_64); | ||
73 | rshifts = 32 + 1 + N_BITS_HEAD_ROOM - lz; | ||
74 | if (rshifts > MAX_RSHIFTS) rshifts = MAX_RSHIFTS; | ||
75 | if (rshifts < MIN_RSHIFTS) rshifts = MIN_RSHIFTS; | ||
76 | |||
77 | if (rshifts > 0) { | ||
78 | C0 = (opus_int32)silk_RSHIFT64(C0_64, rshifts ); | ||
79 | } else { | ||
80 | C0 = silk_LSHIFT32((opus_int32)C0_64, -rshifts ); | ||
81 | } | ||
82 | |||
83 | CAb[ 0 ] = CAf[ 0 ] = C0 + silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ) + 1; /* Q(-rshifts) */ | ||
84 | silk_memset( C_first_row, 0, SILK_MAX_ORDER_LPC * sizeof( opus_int32 ) ); | ||
85 | if( rshifts > 0 ) { | ||
86 | for( s = 0; s < nb_subfr; s++ ) { | ||
87 | x_ptr = x + s * subfr_length; | ||
88 | for( n = 1; n < D + 1; n++ ) { | ||
89 | C_first_row[ n - 1 ] += (opus_int32)silk_RSHIFT64( | ||
90 | silk_inner_prod16_aligned_64( x_ptr, x_ptr + n, subfr_length - n, arch ), rshifts ); | ||
91 | } | ||
92 | } | ||
93 | } else { | ||
94 | for( s = 0; s < nb_subfr; s++ ) { | ||
95 | int i; | ||
96 | opus_int32 d; | ||
97 | x_ptr = x + s * subfr_length; | ||
98 | celt_pitch_xcorr(x_ptr, x_ptr + 1, xcorr, subfr_length - D, D, arch ); | ||
99 | for( n = 1; n < D + 1; n++ ) { | ||
100 | for ( i = n + subfr_length - D, d = 0; i < subfr_length; i++ ) | ||
101 | d = MAC16_16( d, x_ptr[ i ], x_ptr[ i - n ] ); | ||
102 | xcorr[ n - 1 ] += d; | ||
103 | } | ||
104 | for( n = 1; n < D + 1; n++ ) { | ||
105 | C_first_row[ n - 1 ] += silk_LSHIFT32( xcorr[ n - 1 ], -rshifts ); | ||
106 | } | ||
107 | } | ||
108 | } | ||
109 | silk_memcpy( C_last_row, C_first_row, SILK_MAX_ORDER_LPC * sizeof( opus_int32 ) ); | ||
110 | |||
111 | /* Initialize */ | ||
112 | CAb[ 0 ] = CAf[ 0 ] = C0 + silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ) + 1; /* Q(-rshifts) */ | ||
113 | |||
114 | invGain_Q30 = (opus_int32)1 << 30; | ||
115 | reached_max_gain = 0; | ||
116 | for( n = 0; n < D; n++ ) { | ||
117 | /* Update first row of correlation matrix (without first element) */ | ||
118 | /* Update last row of correlation matrix (without last element, stored in reversed order) */ | ||
119 | /* Update C * Af */ | ||
120 | /* Update C * flipud(Af) (stored in reversed order) */ | ||
121 | if( rshifts > -2 ) { | ||
122 | for( s = 0; s < nb_subfr; s++ ) { | ||
123 | x_ptr = x + s * subfr_length; | ||
124 | x1 = -silk_LSHIFT32( (opus_int32)x_ptr[ n ], 16 - rshifts ); /* Q(16-rshifts) */ | ||
125 | x2 = -silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], 16 - rshifts ); /* Q(16-rshifts) */ | ||
126 | tmp1 = silk_LSHIFT32( (opus_int32)x_ptr[ n ], QA - 16 ); /* Q(QA-16) */ | ||
127 | tmp2 = silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], QA - 16 ); /* Q(QA-16) */ | ||
128 | for( k = 0; k < n; k++ ) { | ||
129 | C_first_row[ k ] = silk_SMLAWB( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); /* Q( -rshifts ) */ | ||
130 | C_last_row[ k ] = silk_SMLAWB( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts ) */ | ||
131 | Atmp_QA = Af_QA[ k ]; | ||
132 | tmp1 = silk_SMLAWB( tmp1, Atmp_QA, x_ptr[ n - k - 1 ] ); /* Q(QA-16) */ | ||
133 | tmp2 = silk_SMLAWB( tmp2, Atmp_QA, x_ptr[ subfr_length - n + k ] ); /* Q(QA-16) */ | ||
134 | } | ||
135 | tmp1 = silk_LSHIFT32( -tmp1, 32 - QA - rshifts ); /* Q(16-rshifts) */ | ||
136 | tmp2 = silk_LSHIFT32( -tmp2, 32 - QA - rshifts ); /* Q(16-rshifts) */ | ||
137 | for( k = 0; k <= n; k++ ) { | ||
138 | CAf[ k ] = silk_SMLAWB( CAf[ k ], tmp1, x_ptr[ n - k ] ); /* Q( -rshift ) */ | ||
139 | CAb[ k ] = silk_SMLAWB( CAb[ k ], tmp2, x_ptr[ subfr_length - n + k - 1 ] ); /* Q( -rshift ) */ | ||
140 | } | ||
141 | } | ||
142 | } else { | ||
143 | for( s = 0; s < nb_subfr; s++ ) { | ||
144 | x_ptr = x + s * subfr_length; | ||
145 | x1 = -silk_LSHIFT32( (opus_int32)x_ptr[ n ], -rshifts ); /* Q( -rshifts ) */ | ||
146 | x2 = -silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], -rshifts ); /* Q( -rshifts ) */ | ||
147 | tmp1 = silk_LSHIFT32( (opus_int32)x_ptr[ n ], 17 ); /* Q17 */ | ||
148 | tmp2 = silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], 17 ); /* Q17 */ | ||
149 | for( k = 0; k < n; k++ ) { | ||
150 | C_first_row[ k ] = silk_MLA( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); /* Q( -rshifts ) */ | ||
151 | C_last_row[ k ] = silk_MLA( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts ) */ | ||
152 | Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 17 ); /* Q17 */ | ||
153 | /* We sometimes have get overflows in the multiplications (even beyond +/- 2^32), | ||
154 | but they cancel each other and the real result seems to always fit in a 32-bit | ||
155 | signed integer. This was determined experimentally, not theoretically (unfortunately). */ | ||
156 | tmp1 = silk_MLA_ovflw( tmp1, x_ptr[ n - k - 1 ], Atmp1 ); /* Q17 */ | ||
157 | tmp2 = silk_MLA_ovflw( tmp2, x_ptr[ subfr_length - n + k ], Atmp1 ); /* Q17 */ | ||
158 | } | ||
159 | tmp1 = -tmp1; /* Q17 */ | ||
160 | tmp2 = -tmp2; /* Q17 */ | ||
161 | for( k = 0; k <= n; k++ ) { | ||
162 | CAf[ k ] = silk_SMLAWW( CAf[ k ], tmp1, | ||
163 | silk_LSHIFT32( (opus_int32)x_ptr[ n - k ], -rshifts - 1 ) ); /* Q( -rshift ) */ | ||
164 | CAb[ k ] = silk_SMLAWW( CAb[ k ], tmp2, | ||
165 | silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n + k - 1 ], -rshifts - 1 ) ); /* Q( -rshift ) */ | ||
166 | } | ||
167 | } | ||
168 | } | ||
169 | |||
170 | /* Calculate nominator and denominator for the next order reflection (parcor) coefficient */ | ||
171 | tmp1 = C_first_row[ n ]; /* Q( -rshifts ) */ | ||
172 | tmp2 = C_last_row[ n ]; /* Q( -rshifts ) */ | ||
173 | num = 0; /* Q( -rshifts ) */ | ||
174 | nrg = silk_ADD32( CAb[ 0 ], CAf[ 0 ] ); /* Q( 1-rshifts ) */ | ||
175 | for( k = 0; k < n; k++ ) { | ||
176 | Atmp_QA = Af_QA[ k ]; | ||
177 | lz = silk_CLZ32( silk_abs( Atmp_QA ) ) - 1; | ||
178 | lz = silk_min( 32 - QA, lz ); | ||
179 | Atmp1 = silk_LSHIFT32( Atmp_QA, lz ); /* Q( QA + lz ) */ | ||
180 | |||
181 | tmp1 = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( C_last_row[ n - k - 1 ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts ) */ | ||
182 | tmp2 = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( C_first_row[ n - k - 1 ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts ) */ | ||
183 | num = silk_ADD_LSHIFT32( num, silk_SMMUL( CAb[ n - k ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts ) */ | ||
184 | nrg = silk_ADD_LSHIFT32( nrg, silk_SMMUL( silk_ADD32( CAb[ k + 1 ], CAf[ k + 1 ] ), | ||
185 | Atmp1 ), 32 - QA - lz ); /* Q( 1-rshifts ) */ | ||
186 | } | ||
187 | CAf[ n + 1 ] = tmp1; /* Q( -rshifts ) */ | ||
188 | CAb[ n + 1 ] = tmp2; /* Q( -rshifts ) */ | ||
189 | num = silk_ADD32( num, tmp2 ); /* Q( -rshifts ) */ | ||
190 | num = silk_LSHIFT32( -num, 1 ); /* Q( 1-rshifts ) */ | ||
191 | |||
192 | /* Calculate the next order reflection (parcor) coefficient */ | ||
193 | if( silk_abs( num ) < nrg ) { | ||
194 | rc_Q31 = silk_DIV32_varQ( num, nrg, 31 ); | ||
195 | } else { | ||
196 | rc_Q31 = ( num > 0 ) ? silk_int32_MAX : silk_int32_MIN; | ||
197 | } | ||
198 | |||
199 | /* Update inverse prediction gain */ | ||
200 | tmp1 = ( (opus_int32)1 << 30 ) - silk_SMMUL( rc_Q31, rc_Q31 ); | ||
201 | tmp1 = silk_LSHIFT( silk_SMMUL( invGain_Q30, tmp1 ), 2 ); | ||
202 | if( tmp1 <= minInvGain_Q30 ) { | ||
203 | /* Max prediction gain exceeded; set reflection coefficient such that max prediction gain is exactly hit */ | ||
204 | tmp2 = ( (opus_int32)1 << 30 ) - silk_DIV32_varQ( minInvGain_Q30, invGain_Q30, 30 ); /* Q30 */ | ||
205 | rc_Q31 = silk_SQRT_APPROX( tmp2 ); /* Q15 */ | ||
206 | if( rc_Q31 > 0 ) { | ||
207 | /* Newton-Raphson iteration */ | ||
208 | rc_Q31 = silk_RSHIFT32( rc_Q31 + silk_DIV32( tmp2, rc_Q31 ), 1 ); /* Q15 */ | ||
209 | rc_Q31 = silk_LSHIFT32( rc_Q31, 16 ); /* Q31 */ | ||
210 | if( num < 0 ) { | ||
211 | /* Ensure adjusted reflection coefficients has the original sign */ | ||
212 | rc_Q31 = -rc_Q31; | ||
213 | } | ||
214 | } | ||
215 | invGain_Q30 = minInvGain_Q30; | ||
216 | reached_max_gain = 1; | ||
217 | } else { | ||
218 | invGain_Q30 = tmp1; | ||
219 | } | ||
220 | |||
221 | /* Update the AR coefficients */ | ||
222 | for( k = 0; k < (n + 1) >> 1; k++ ) { | ||
223 | tmp1 = Af_QA[ k ]; /* QA */ | ||
224 | tmp2 = Af_QA[ n - k - 1 ]; /* QA */ | ||
225 | Af_QA[ k ] = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( tmp2, rc_Q31 ), 1 ); /* QA */ | ||
226 | Af_QA[ n - k - 1 ] = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( tmp1, rc_Q31 ), 1 ); /* QA */ | ||
227 | } | ||
228 | Af_QA[ n ] = silk_RSHIFT32( rc_Q31, 31 - QA ); /* QA */ | ||
229 | |||
230 | if( reached_max_gain ) { | ||
231 | /* Reached max prediction gain; set remaining coefficients to zero and exit loop */ | ||
232 | for( k = n + 1; k < D; k++ ) { | ||
233 | Af_QA[ k ] = 0; | ||
234 | } | ||
235 | break; | ||
236 | } | ||
237 | |||
238 | /* Update C * Af and C * Ab */ | ||
239 | for( k = 0; k <= n + 1; k++ ) { | ||
240 | tmp1 = CAf[ k ]; /* Q( -rshifts ) */ | ||
241 | tmp2 = CAb[ n - k + 1 ]; /* Q( -rshifts ) */ | ||
242 | CAf[ k ] = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( tmp2, rc_Q31 ), 1 ); /* Q( -rshifts ) */ | ||
243 | CAb[ n - k + 1 ] = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( tmp1, rc_Q31 ), 1 ); /* Q( -rshifts ) */ | ||
244 | } | ||
245 | } | ||
246 | |||
247 | if( reached_max_gain ) { | ||
248 | for( k = 0; k < D; k++ ) { | ||
249 | /* Scale coefficients */ | ||
250 | A_Q16[ k ] = -silk_RSHIFT_ROUND( Af_QA[ k ], QA - 16 ); | ||
251 | } | ||
252 | /* Subtract energy of preceding samples from C0 */ | ||
253 | if( rshifts > 0 ) { | ||
254 | for( s = 0; s < nb_subfr; s++ ) { | ||
255 | x_ptr = x + s * subfr_length; | ||
256 | C0 -= (opus_int32)silk_RSHIFT64( silk_inner_prod16_aligned_64( x_ptr, x_ptr, D, arch ), rshifts ); | ||
257 | } | ||
258 | } else { | ||
259 | for( s = 0; s < nb_subfr; s++ ) { | ||
260 | x_ptr = x + s * subfr_length; | ||
261 | C0 -= silk_LSHIFT32( silk_inner_prod_aligned( x_ptr, x_ptr, D, arch), -rshifts); | ||
262 | } | ||
263 | } | ||
264 | /* Approximate residual energy */ | ||
265 | *res_nrg = silk_LSHIFT( silk_SMMUL( invGain_Q30, C0 ), 2 ); | ||
266 | *res_nrg_Q = -rshifts; | ||
267 | } else { | ||
268 | /* Return residual energy */ | ||
269 | nrg = CAf[ 0 ]; /* Q( -rshifts ) */ | ||
270 | tmp1 = (opus_int32)1 << 16; /* Q16 */ | ||
271 | for( k = 0; k < D; k++ ) { | ||
272 | Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 16 ); /* Q16 */ | ||
273 | nrg = silk_SMLAWW( nrg, CAf[ k + 1 ], Atmp1 ); /* Q( -rshifts ) */ | ||
274 | tmp1 = silk_SMLAWW( tmp1, Atmp1, Atmp1 ); /* Q16 */ | ||
275 | A_Q16[ k ] = -Atmp1; | ||
276 | } | ||
277 | *res_nrg = silk_SMLAWW( nrg, silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ), -tmp1 );/* Q( -rshifts ) */ | ||
278 | *res_nrg_Q = -rshifts; | ||
279 | } | ||
280 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/corrMatrix_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/corrMatrix_FIX.c new file mode 100644 index 0000000000..1b4a29c232 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/fixed/corrMatrix_FIX.c | |||
@@ -0,0 +1,150 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | /********************************************************************** | ||
33 | * Correlation Matrix Computations for LS estimate. | ||
34 | **********************************************************************/ | ||
35 | |||
36 | #include "main_FIX.h" | ||
37 | |||
38 | /* Calculates correlation vector X'*t */ | ||
39 | void silk_corrVector_FIX( | ||
40 | const opus_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */ | ||
41 | const opus_int16 *t, /* I Target vector [L] */ | ||
42 | const opus_int L, /* I Length of vectors */ | ||
43 | const opus_int order, /* I Max lag for correlation */ | ||
44 | opus_int32 *Xt, /* O Pointer to X'*t correlation vector [order] */ | ||
45 | const opus_int rshifts, /* I Right shifts of correlations */ | ||
46 | int arch /* I Run-time architecture */ | ||
47 | ) | ||
48 | { | ||
49 | opus_int lag, i; | ||
50 | const opus_int16 *ptr1, *ptr2; | ||
51 | opus_int32 inner_prod; | ||
52 | |||
53 | ptr1 = &x[ order - 1 ]; /* Points to first sample of column 0 of X: X[:,0] */ | ||
54 | ptr2 = t; | ||
55 | /* Calculate X'*t */ | ||
56 | if( rshifts > 0 ) { | ||
57 | /* Right shifting used */ | ||
58 | for( lag = 0; lag < order; lag++ ) { | ||
59 | inner_prod = 0; | ||
60 | for( i = 0; i < L; i++ ) { | ||
61 | inner_prod = silk_ADD_RSHIFT32( inner_prod, silk_SMULBB( ptr1[ i ], ptr2[i] ), rshifts ); | ||
62 | } | ||
63 | Xt[ lag ] = inner_prod; /* X[:,lag]'*t */ | ||
64 | ptr1--; /* Go to next column of X */ | ||
65 | } | ||
66 | } else { | ||
67 | silk_assert( rshifts == 0 ); | ||
68 | for( lag = 0; lag < order; lag++ ) { | ||
69 | Xt[ lag ] = silk_inner_prod_aligned( ptr1, ptr2, L, arch ); /* X[:,lag]'*t */ | ||
70 | ptr1--; /* Go to next column of X */ | ||
71 | } | ||
72 | } | ||
73 | } | ||
74 | |||
75 | /* Calculates correlation matrix X'*X */ | ||
76 | void silk_corrMatrix_FIX( | ||
77 | const opus_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */ | ||
78 | const opus_int L, /* I Length of vectors */ | ||
79 | const opus_int order, /* I Max lag for correlation */ | ||
80 | opus_int32 *XX, /* O Pointer to X'*X correlation matrix [ order x order ] */ | ||
81 | opus_int32 *nrg, /* O Energy of x vector */ | ||
82 | opus_int *rshifts, /* O Right shifts of correlations and energy */ | ||
83 | int arch /* I Run-time architecture */ | ||
84 | ) | ||
85 | { | ||
86 | opus_int i, j, lag; | ||
87 | opus_int32 energy; | ||
88 | const opus_int16 *ptr1, *ptr2; | ||
89 | |||
90 | /* Calculate energy to find shift used to fit in 32 bits */ | ||
91 | silk_sum_sqr_shift( nrg, rshifts, x, L + order - 1 ); | ||
92 | energy = *nrg; | ||
93 | |||
94 | /* Calculate energy of first column (0) of X: X[:,0]'*X[:,0] */ | ||
95 | /* Remove contribution of first order - 1 samples */ | ||
96 | for( i = 0; i < order - 1; i++ ) { | ||
97 | energy -= silk_RSHIFT32( silk_SMULBB( x[ i ], x[ i ] ), *rshifts ); | ||
98 | } | ||
99 | |||
100 | /* Calculate energy of remaining columns of X: X[:,j]'*X[:,j] */ | ||
101 | /* Fill out the diagonal of the correlation matrix */ | ||
102 | matrix_ptr( XX, 0, 0, order ) = energy; | ||
103 | silk_assert( energy >= 0 ); | ||
104 | ptr1 = &x[ order - 1 ]; /* First sample of column 0 of X */ | ||
105 | for( j = 1; j < order; j++ ) { | ||
106 | energy = silk_SUB32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ L - j ], ptr1[ L - j ] ), *rshifts ) ); | ||
107 | energy = silk_ADD32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ -j ], ptr1[ -j ] ), *rshifts ) ); | ||
108 | matrix_ptr( XX, j, j, order ) = energy; | ||
109 | silk_assert( energy >= 0 ); | ||
110 | } | ||
111 | |||
112 | ptr2 = &x[ order - 2 ]; /* First sample of column 1 of X */ | ||
113 | /* Calculate the remaining elements of the correlation matrix */ | ||
114 | if( *rshifts > 0 ) { | ||
115 | /* Right shifting used */ | ||
116 | for( lag = 1; lag < order; lag++ ) { | ||
117 | /* Inner product of column 0 and column lag: X[:,0]'*X[:,lag] */ | ||
118 | energy = 0; | ||
119 | for( i = 0; i < L; i++ ) { | ||
120 | energy += silk_RSHIFT32( silk_SMULBB( ptr1[ i ], ptr2[i] ), *rshifts ); | ||
121 | } | ||
122 | /* Calculate remaining off diagonal: X[:,j]'*X[:,j + lag] */ | ||
123 | matrix_ptr( XX, lag, 0, order ) = energy; | ||
124 | matrix_ptr( XX, 0, lag, order ) = energy; | ||
125 | for( j = 1; j < ( order - lag ); j++ ) { | ||
126 | energy = silk_SUB32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ L - j ], ptr2[ L - j ] ), *rshifts ) ); | ||
127 | energy = silk_ADD32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ -j ], ptr2[ -j ] ), *rshifts ) ); | ||
128 | matrix_ptr( XX, lag + j, j, order ) = energy; | ||
129 | matrix_ptr( XX, j, lag + j, order ) = energy; | ||
130 | } | ||
131 | ptr2--; /* Update pointer to first sample of next column (lag) in X */ | ||
132 | } | ||
133 | } else { | ||
134 | for( lag = 1; lag < order; lag++ ) { | ||
135 | /* Inner product of column 0 and column lag: X[:,0]'*X[:,lag] */ | ||
136 | energy = silk_inner_prod_aligned( ptr1, ptr2, L, arch ); | ||
137 | matrix_ptr( XX, lag, 0, order ) = energy; | ||
138 | matrix_ptr( XX, 0, lag, order ) = energy; | ||
139 | /* Calculate remaining off diagonal: X[:,j]'*X[:,j + lag] */ | ||
140 | for( j = 1; j < ( order - lag ); j++ ) { | ||
141 | energy = silk_SUB32( energy, silk_SMULBB( ptr1[ L - j ], ptr2[ L - j ] ) ); | ||
142 | energy = silk_SMLABB( energy, ptr1[ -j ], ptr2[ -j ] ); | ||
143 | matrix_ptr( XX, lag + j, j, order ) = energy; | ||
144 | matrix_ptr( XX, j, lag + j, order ) = energy; | ||
145 | } | ||
146 | ptr2--;/* Update pointer to first sample of next column (lag) in X */ | ||
147 | } | ||
148 | } | ||
149 | } | ||
150 | |||
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/encode_frame_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/encode_frame_FIX.c new file mode 100644 index 0000000000..a02bf87dbb --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/fixed/encode_frame_FIX.c | |||
@@ -0,0 +1,448 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include <stdlib.h> | ||
33 | #include "main_FIX.h" | ||
34 | #include "stack_alloc.h" | ||
35 | #include "tuning_parameters.h" | ||
36 | |||
37 | /* Low Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode with lower bitrate */ | ||
38 | static OPUS_INLINE void silk_LBRR_encode_FIX( | ||
39 | silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */ | ||
40 | silk_encoder_control_FIX *psEncCtrl, /* I/O Pointer to Silk FIX encoder control struct */ | ||
41 | const opus_int16 x16[], /* I Input signal */ | ||
42 | opus_int condCoding /* I The type of conditional coding used so far for this frame */ | ||
43 | ); | ||
44 | |||
45 | void silk_encode_do_VAD_FIX( | ||
46 | silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */ | ||
47 | opus_int activity /* I Decision of Opus voice activity detector */ | ||
48 | ) | ||
49 | { | ||
50 | const opus_int activity_threshold = SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ); | ||
51 | |||
52 | /****************************/ | ||
53 | /* Voice Activity Detection */ | ||
54 | /****************************/ | ||
55 | silk_VAD_GetSA_Q8( &psEnc->sCmn, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.arch ); | ||
56 | /* If Opus VAD is inactive and Silk VAD is active: lower Silk VAD to just under the threshold */ | ||
57 | if( activity == VAD_NO_ACTIVITY && psEnc->sCmn.speech_activity_Q8 >= activity_threshold ) { | ||
58 | psEnc->sCmn.speech_activity_Q8 = activity_threshold - 1; | ||
59 | } | ||
60 | |||
61 | /**************************************************/ | ||
62 | /* Convert speech activity into VAD and DTX flags */ | ||
63 | /**************************************************/ | ||
64 | if( psEnc->sCmn.speech_activity_Q8 < activity_threshold ) { | ||
65 | psEnc->sCmn.indices.signalType = TYPE_NO_VOICE_ACTIVITY; | ||
66 | psEnc->sCmn.noSpeechCounter++; | ||
67 | if( psEnc->sCmn.noSpeechCounter <= NB_SPEECH_FRAMES_BEFORE_DTX ) { | ||
68 | psEnc->sCmn.inDTX = 0; | ||
69 | } else if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NB_SPEECH_FRAMES_BEFORE_DTX ) { | ||
70 | psEnc->sCmn.noSpeechCounter = NB_SPEECH_FRAMES_BEFORE_DTX; | ||
71 | psEnc->sCmn.inDTX = 0; | ||
72 | } | ||
73 | psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 0; | ||
74 | } else { | ||
75 | psEnc->sCmn.noSpeechCounter = 0; | ||
76 | psEnc->sCmn.inDTX = 0; | ||
77 | psEnc->sCmn.indices.signalType = TYPE_UNVOICED; | ||
78 | psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 1; | ||
79 | } | ||
80 | } | ||
81 | |||
82 | /****************/ | ||
83 | /* Encode frame */ | ||
84 | /****************/ | ||
85 | opus_int silk_encode_frame_FIX( | ||
86 | silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */ | ||
87 | opus_int32 *pnBytesOut, /* O Pointer to number of payload bytes; */ | ||
88 | ec_enc *psRangeEnc, /* I/O compressor data structure */ | ||
89 | opus_int condCoding, /* I The type of conditional coding to use */ | ||
90 | opus_int maxBits, /* I If > 0: maximum number of output bits */ | ||
91 | opus_int useCBR /* I Flag to force constant-bitrate operation */ | ||
92 | ) | ||
93 | { | ||
94 | silk_encoder_control_FIX sEncCtrl; | ||
95 | opus_int i, iter, maxIter, found_upper, found_lower, ret = 0; | ||
96 | opus_int16 *x_frame; | ||
97 | ec_enc sRangeEnc_copy, sRangeEnc_copy2; | ||
98 | silk_nsq_state sNSQ_copy, sNSQ_copy2; | ||
99 | opus_int32 seed_copy, nBits, nBits_lower, nBits_upper, gainMult_lower, gainMult_upper; | ||
100 | opus_int32 gainsID, gainsID_lower, gainsID_upper; | ||
101 | opus_int16 gainMult_Q8; | ||
102 | opus_int16 ec_prevLagIndex_copy; | ||
103 | opus_int ec_prevSignalType_copy; | ||
104 | opus_int8 LastGainIndex_copy2; | ||
105 | opus_int gain_lock[ MAX_NB_SUBFR ] = {0}; | ||
106 | opus_int16 best_gain_mult[ MAX_NB_SUBFR ]; | ||
107 | opus_int best_sum[ MAX_NB_SUBFR ]; | ||
108 | SAVE_STACK; | ||
109 | |||
110 | /* This is totally unnecessary but many compilers (including gcc) are too dumb to realise it */ | ||
111 | LastGainIndex_copy2 = nBits_lower = nBits_upper = gainMult_lower = gainMult_upper = 0; | ||
112 | |||
113 | psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3; | ||
114 | |||
115 | /**************************************************************/ | ||
116 | /* Set up Input Pointers, and insert frame in input buffer */ | ||
117 | /*************************************************************/ | ||
118 | /* start of frame to encode */ | ||
119 | x_frame = psEnc->x_buf + psEnc->sCmn.ltp_mem_length; | ||
120 | |||
121 | /***************************************/ | ||
122 | /* Ensure smooth bandwidth transitions */ | ||
123 | /***************************************/ | ||
124 | silk_LP_variable_cutoff( &psEnc->sCmn.sLP, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length ); | ||
125 | |||
126 | /*******************************************/ | ||
127 | /* Copy new frame to front of input buffer */ | ||
128 | /*******************************************/ | ||
129 | silk_memcpy( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length * sizeof( opus_int16 ) ); | ||
130 | |||
131 | if( !psEnc->sCmn.prefillFlag ) { | ||
132 | VARDECL( opus_int16, res_pitch ); | ||
133 | VARDECL( opus_uint8, ec_buf_copy ); | ||
134 | opus_int16 *res_pitch_frame; | ||
135 | |||
136 | ALLOC( res_pitch, | ||
137 | psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length | ||
138 | + psEnc->sCmn.ltp_mem_length, opus_int16 ); | ||
139 | /* start of pitch LPC residual frame */ | ||
140 | res_pitch_frame = res_pitch + psEnc->sCmn.ltp_mem_length; | ||
141 | |||
142 | /*****************************************/ | ||
143 | /* Find pitch lags, initial LPC analysis */ | ||
144 | /*****************************************/ | ||
145 | silk_find_pitch_lags_FIX( psEnc, &sEncCtrl, res_pitch, x_frame - psEnc->sCmn.ltp_mem_length, psEnc->sCmn.arch ); | ||
146 | |||
147 | /************************/ | ||
148 | /* Noise shape analysis */ | ||
149 | /************************/ | ||
150 | silk_noise_shape_analysis_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame, psEnc->sCmn.arch ); | ||
151 | |||
152 | /***************************************************/ | ||
153 | /* Find linear prediction coefficients (LPC + LTP) */ | ||
154 | /***************************************************/ | ||
155 | silk_find_pred_coefs_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame, condCoding ); | ||
156 | |||
157 | /****************************************/ | ||
158 | /* Process gains */ | ||
159 | /****************************************/ | ||
160 | silk_process_gains_FIX( psEnc, &sEncCtrl, condCoding ); | ||
161 | |||
162 | /****************************************/ | ||
163 | /* Low Bitrate Redundant Encoding */ | ||
164 | /****************************************/ | ||
165 | silk_LBRR_encode_FIX( psEnc, &sEncCtrl, x_frame, condCoding ); | ||
166 | |||
167 | /* Loop over quantizer and entropy coding to control bitrate */ | ||
168 | maxIter = 6; | ||
169 | gainMult_Q8 = SILK_FIX_CONST( 1, 8 ); | ||
170 | found_lower = 0; | ||
171 | found_upper = 0; | ||
172 | gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr ); | ||
173 | gainsID_lower = -1; | ||
174 | gainsID_upper = -1; | ||
175 | /* Copy part of the input state */ | ||
176 | silk_memcpy( &sRangeEnc_copy, psRangeEnc, sizeof( ec_enc ) ); | ||
177 | silk_memcpy( &sNSQ_copy, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); | ||
178 | seed_copy = psEnc->sCmn.indices.Seed; | ||
179 | ec_prevLagIndex_copy = psEnc->sCmn.ec_prevLagIndex; | ||
180 | ec_prevSignalType_copy = psEnc->sCmn.ec_prevSignalType; | ||
181 | ALLOC( ec_buf_copy, 1275, opus_uint8 ); | ||
182 | for( iter = 0; ; iter++ ) { | ||
183 | if( gainsID == gainsID_lower ) { | ||
184 | nBits = nBits_lower; | ||
185 | } else if( gainsID == gainsID_upper ) { | ||
186 | nBits = nBits_upper; | ||
187 | } else { | ||
188 | /* Restore part of the input state */ | ||
189 | if( iter > 0 ) { | ||
190 | silk_memcpy( psRangeEnc, &sRangeEnc_copy, sizeof( ec_enc ) ); | ||
191 | silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy, sizeof( silk_nsq_state ) ); | ||
192 | psEnc->sCmn.indices.Seed = seed_copy; | ||
193 | psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy; | ||
194 | psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy; | ||
195 | } | ||
196 | |||
197 | /*****************************************/ | ||
198 | /* Noise shaping quantization */ | ||
199 | /*****************************************/ | ||
200 | if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) { | ||
201 | silk_NSQ_del_dec( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, x_frame, psEnc->sCmn.pulses, | ||
202 | sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR_Q13, sEncCtrl.HarmShapeGain_Q14, | ||
203 | sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14, | ||
204 | psEnc->sCmn.arch ); | ||
205 | } else { | ||
206 | silk_NSQ( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, x_frame, psEnc->sCmn.pulses, | ||
207 | sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR_Q13, sEncCtrl.HarmShapeGain_Q14, | ||
208 | sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14, | ||
209 | psEnc->sCmn.arch); | ||
210 | } | ||
211 | |||
212 | if ( iter == maxIter && !found_lower ) { | ||
213 | silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) ); | ||
214 | } | ||
215 | |||
216 | /****************************************/ | ||
217 | /* Encode Parameters */ | ||
218 | /****************************************/ | ||
219 | silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding ); | ||
220 | |||
221 | /****************************************/ | ||
222 | /* Encode Excitation Signal */ | ||
223 | /****************************************/ | ||
224 | silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType, | ||
225 | psEnc->sCmn.pulses, psEnc->sCmn.frame_length ); | ||
226 | |||
227 | nBits = ec_tell( psRangeEnc ); | ||
228 | |||
229 | /* If we still bust after the last iteration, do some damage control. */ | ||
230 | if ( iter == maxIter && !found_lower && nBits > maxBits ) { | ||
231 | silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) ); | ||
232 | |||
233 | /* Keep gains the same as the last frame. */ | ||
234 | psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev; | ||
235 | for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { | ||
236 | psEnc->sCmn.indices.GainsIndices[ i ] = 4; | ||
237 | } | ||
238 | if (condCoding != CODE_CONDITIONALLY) { | ||
239 | psEnc->sCmn.indices.GainsIndices[ 0 ] = sEncCtrl.lastGainIndexPrev; | ||
240 | } | ||
241 | psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy; | ||
242 | psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy; | ||
243 | /* Clear all pulses. */ | ||
244 | for ( i = 0; i < psEnc->sCmn.frame_length; i++ ) { | ||
245 | psEnc->sCmn.pulses[ i ] = 0; | ||
246 | } | ||
247 | |||
248 | silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding ); | ||
249 | |||
250 | silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType, | ||
251 | psEnc->sCmn.pulses, psEnc->sCmn.frame_length ); | ||
252 | |||
253 | nBits = ec_tell( psRangeEnc ); | ||
254 | } | ||
255 | |||
256 | if( useCBR == 0 && iter == 0 && nBits <= maxBits ) { | ||
257 | break; | ||
258 | } | ||
259 | } | ||
260 | |||
261 | if( iter == maxIter ) { | ||
262 | if( found_lower && ( gainsID == gainsID_lower || nBits > maxBits ) ) { | ||
263 | /* Restore output state from earlier iteration that did meet the bitrate budget */ | ||
264 | silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) ); | ||
265 | celt_assert( sRangeEnc_copy2.offs <= 1275 ); | ||
266 | silk_memcpy( psRangeEnc->buf, ec_buf_copy, sRangeEnc_copy2.offs ); | ||
267 | silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy2, sizeof( silk_nsq_state ) ); | ||
268 | psEnc->sShape.LastGainIndex = LastGainIndex_copy2; | ||
269 | } | ||
270 | break; | ||
271 | } | ||
272 | |||
273 | if( nBits > maxBits ) { | ||
274 | if( found_lower == 0 && iter >= 2 ) { | ||
275 | /* Adjust the quantizer's rate/distortion tradeoff and discard previous "upper" results */ | ||
276 | sEncCtrl.Lambda_Q10 = silk_ADD_RSHIFT32( sEncCtrl.Lambda_Q10, sEncCtrl.Lambda_Q10, 1 ); | ||
277 | found_upper = 0; | ||
278 | gainsID_upper = -1; | ||
279 | } else { | ||
280 | found_upper = 1; | ||
281 | nBits_upper = nBits; | ||
282 | gainMult_upper = gainMult_Q8; | ||
283 | gainsID_upper = gainsID; | ||
284 | } | ||
285 | } else if( nBits < maxBits - 5 ) { | ||
286 | found_lower = 1; | ||
287 | nBits_lower = nBits; | ||
288 | gainMult_lower = gainMult_Q8; | ||
289 | if( gainsID != gainsID_lower ) { | ||
290 | gainsID_lower = gainsID; | ||
291 | /* Copy part of the output state */ | ||
292 | silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) ); | ||
293 | celt_assert( psRangeEnc->offs <= 1275 ); | ||
294 | silk_memcpy( ec_buf_copy, psRangeEnc->buf, psRangeEnc->offs ); | ||
295 | silk_memcpy( &sNSQ_copy2, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); | ||
296 | LastGainIndex_copy2 = psEnc->sShape.LastGainIndex; | ||
297 | } | ||
298 | } else { | ||
299 | /* Within 5 bits of budget: close enough */ | ||
300 | break; | ||
301 | } | ||
302 | |||
303 | if ( !found_lower && nBits > maxBits ) { | ||
304 | int j; | ||
305 | for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { | ||
306 | int sum=0; | ||
307 | for ( j = i*psEnc->sCmn.subfr_length; j < (i+1)*psEnc->sCmn.subfr_length; j++ ) { | ||
308 | sum += abs( psEnc->sCmn.pulses[j] ); | ||
309 | } | ||
310 | if ( iter == 0 || (sum < best_sum[i] && !gain_lock[i]) ) { | ||
311 | best_sum[i] = sum; | ||
312 | best_gain_mult[i] = gainMult_Q8; | ||
313 | } else { | ||
314 | gain_lock[i] = 1; | ||
315 | } | ||
316 | } | ||
317 | } | ||
318 | if( ( found_lower & found_upper ) == 0 ) { | ||
319 | /* Adjust gain according to high-rate rate/distortion curve */ | ||
320 | if( nBits > maxBits ) { | ||
321 | if (gainMult_Q8 < 16384) { | ||
322 | gainMult_Q8 *= 2; | ||
323 | } else { | ||
324 | gainMult_Q8 = 32767; | ||
325 | } | ||
326 | } else { | ||
327 | opus_int32 gain_factor_Q16; | ||
328 | gain_factor_Q16 = silk_log2lin( silk_LSHIFT( nBits - maxBits, 7 ) / psEnc->sCmn.frame_length + SILK_FIX_CONST( 16, 7 ) ); | ||
329 | gainMult_Q8 = silk_SMULWB( gain_factor_Q16, gainMult_Q8 ); | ||
330 | } | ||
331 | |||
332 | } else { | ||
333 | /* Adjust gain by interpolating */ | ||
334 | gainMult_Q8 = gainMult_lower + silk_DIV32_16( silk_MUL( gainMult_upper - gainMult_lower, maxBits - nBits_lower ), nBits_upper - nBits_lower ); | ||
335 | /* New gain multplier must be between 25% and 75% of old range (note that gainMult_upper < gainMult_lower) */ | ||
336 | if( gainMult_Q8 > silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ) ) { | ||
337 | gainMult_Q8 = silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ); | ||
338 | } else | ||
339 | if( gainMult_Q8 < silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ) ) { | ||
340 | gainMult_Q8 = silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ); | ||
341 | } | ||
342 | } | ||
343 | |||
344 | for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { | ||
345 | opus_int16 tmp; | ||
346 | if ( gain_lock[i] ) { | ||
347 | tmp = best_gain_mult[i]; | ||
348 | } else { | ||
349 | tmp = gainMult_Q8; | ||
350 | } | ||
351 | sEncCtrl.Gains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], tmp ), 8 ); | ||
352 | } | ||
353 | |||
354 | /* Quantize gains */ | ||
355 | psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev; | ||
356 | silk_gains_quant( psEnc->sCmn.indices.GainsIndices, sEncCtrl.Gains_Q16, | ||
357 | &psEnc->sShape.LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr ); | ||
358 | |||
359 | /* Unique identifier of gains vector */ | ||
360 | gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr ); | ||
361 | } | ||
362 | } | ||
363 | |||
364 | /* Update input buffer */ | ||
365 | silk_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ], | ||
366 | ( psEnc->sCmn.ltp_mem_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( opus_int16 ) ); | ||
367 | |||
368 | /* Exit without entropy coding */ | ||
369 | if( psEnc->sCmn.prefillFlag ) { | ||
370 | /* No payload */ | ||
371 | *pnBytesOut = 0; | ||
372 | RESTORE_STACK; | ||
373 | return ret; | ||
374 | } | ||
375 | |||
376 | /* Parameters needed for next frame */ | ||
377 | psEnc->sCmn.prevLag = sEncCtrl.pitchL[ psEnc->sCmn.nb_subfr - 1 ]; | ||
378 | psEnc->sCmn.prevSignalType = psEnc->sCmn.indices.signalType; | ||
379 | |||
380 | /****************************************/ | ||
381 | /* Finalize payload */ | ||
382 | /****************************************/ | ||
383 | psEnc->sCmn.first_frame_after_reset = 0; | ||
384 | /* Payload size */ | ||
385 | *pnBytesOut = silk_RSHIFT( ec_tell( psRangeEnc ) + 7, 3 ); | ||
386 | |||
387 | RESTORE_STACK; | ||
388 | return ret; | ||
389 | } | ||
390 | |||
391 | /* Low-Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode excitation at lower bitrate */ | ||
392 | static OPUS_INLINE void silk_LBRR_encode_FIX( | ||
393 | silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */ | ||
394 | silk_encoder_control_FIX *psEncCtrl, /* I/O Pointer to Silk FIX encoder control struct */ | ||
395 | const opus_int16 x16[], /* I Input signal */ | ||
396 | opus_int condCoding /* I The type of conditional coding used so far for this frame */ | ||
397 | ) | ||
398 | { | ||
399 | opus_int32 TempGains_Q16[ MAX_NB_SUBFR ]; | ||
400 | SideInfoIndices *psIndices_LBRR = &psEnc->sCmn.indices_LBRR[ psEnc->sCmn.nFramesEncoded ]; | ||
401 | silk_nsq_state sNSQ_LBRR; | ||
402 | |||
403 | /*******************************************/ | ||
404 | /* Control use of inband LBRR */ | ||
405 | /*******************************************/ | ||
406 | if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.speech_activity_Q8 > SILK_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) ) { | ||
407 | psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded ] = 1; | ||
408 | |||
409 | /* Copy noise shaping quantizer state and quantization indices from regular encoding */ | ||
410 | silk_memcpy( &sNSQ_LBRR, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); | ||
411 | silk_memcpy( psIndices_LBRR, &psEnc->sCmn.indices, sizeof( SideInfoIndices ) ); | ||
412 | |||
413 | /* Save original gains */ | ||
414 | silk_memcpy( TempGains_Q16, psEncCtrl->Gains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) ); | ||
415 | |||
416 | if( psEnc->sCmn.nFramesEncoded == 0 || psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded - 1 ] == 0 ) { | ||
417 | /* First frame in packet or previous frame not LBRR coded */ | ||
418 | psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex; | ||
419 | |||
420 | /* Increase Gains to get target LBRR rate */ | ||
421 | psIndices_LBRR->GainsIndices[ 0 ] = psIndices_LBRR->GainsIndices[ 0 ] + psEnc->sCmn.LBRR_GainIncreases; | ||
422 | psIndices_LBRR->GainsIndices[ 0 ] = silk_min_int( psIndices_LBRR->GainsIndices[ 0 ], N_LEVELS_QGAIN - 1 ); | ||
423 | } | ||
424 | |||
425 | /* Decode to get gains in sync with decoder */ | ||
426 | /* Overwrite unquantized gains with quantized gains */ | ||
427 | silk_gains_dequant( psEncCtrl->Gains_Q16, psIndices_LBRR->GainsIndices, | ||
428 | &psEnc->sCmn.LBRRprevLastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr ); | ||
429 | |||
430 | /*****************************************/ | ||
431 | /* Noise shaping quantization */ | ||
432 | /*****************************************/ | ||
433 | if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) { | ||
434 | silk_NSQ_del_dec( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, x16, | ||
435 | psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14, | ||
436 | psEncCtrl->AR_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14, | ||
437 | psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14, psEnc->sCmn.arch ); | ||
438 | } else { | ||
439 | silk_NSQ( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, x16, | ||
440 | psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14, | ||
441 | psEncCtrl->AR_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14, | ||
442 | psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14, psEnc->sCmn.arch ); | ||
443 | } | ||
444 | |||
445 | /* Restore original gains */ | ||
446 | silk_memcpy( psEncCtrl->Gains_Q16, TempGains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) ); | ||
447 | } | ||
448 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/find_LPC_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/find_LPC_FIX.c new file mode 100644 index 0000000000..c762a0f2a2 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/fixed/find_LPC_FIX.c | |||
@@ -0,0 +1,151 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main_FIX.h" | ||
33 | #include "stack_alloc.h" | ||
34 | #include "tuning_parameters.h" | ||
35 | |||
36 | /* Finds LPC vector from correlations, and converts to NLSF */ | ||
37 | void silk_find_LPC_FIX( | ||
38 | silk_encoder_state *psEncC, /* I/O Encoder state */ | ||
39 | opus_int16 NLSF_Q15[], /* O NLSFs */ | ||
40 | const opus_int16 x[], /* I Input signal */ | ||
41 | const opus_int32 minInvGain_Q30 /* I Inverse of max prediction gain */ | ||
42 | ) | ||
43 | { | ||
44 | opus_int k, subfr_length; | ||
45 | opus_int32 a_Q16[ MAX_LPC_ORDER ]; | ||
46 | opus_int isInterpLower, shift; | ||
47 | opus_int32 res_nrg0, res_nrg1; | ||
48 | opus_int rshift0, rshift1; | ||
49 | |||
50 | /* Used only for LSF interpolation */ | ||
51 | opus_int32 a_tmp_Q16[ MAX_LPC_ORDER ], res_nrg_interp, res_nrg, res_tmp_nrg; | ||
52 | opus_int res_nrg_interp_Q, res_nrg_Q, res_tmp_nrg_Q; | ||
53 | opus_int16 a_tmp_Q12[ MAX_LPC_ORDER ]; | ||
54 | opus_int16 NLSF0_Q15[ MAX_LPC_ORDER ]; | ||
55 | SAVE_STACK; | ||
56 | |||
57 | subfr_length = psEncC->subfr_length + psEncC->predictLPCOrder; | ||
58 | |||
59 | /* Default: no interpolation */ | ||
60 | psEncC->indices.NLSFInterpCoef_Q2 = 4; | ||
61 | |||
62 | /* Burg AR analysis for the full frame */ | ||
63 | silk_burg_modified( &res_nrg, &res_nrg_Q, a_Q16, x, minInvGain_Q30, subfr_length, psEncC->nb_subfr, psEncC->predictLPCOrder, psEncC->arch ); | ||
64 | |||
65 | if( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) { | ||
66 | VARDECL( opus_int16, LPC_res ); | ||
67 | |||
68 | /* Optimal solution for last 10 ms */ | ||
69 | silk_burg_modified( &res_tmp_nrg, &res_tmp_nrg_Q, a_tmp_Q16, x + 2 * subfr_length, minInvGain_Q30, subfr_length, 2, psEncC->predictLPCOrder, psEncC->arch ); | ||
70 | |||
71 | /* subtract residual energy here, as that's easier than adding it to the */ | ||
72 | /* residual energy of the first 10 ms in each iteration of the search below */ | ||
73 | shift = res_tmp_nrg_Q - res_nrg_Q; | ||
74 | if( shift >= 0 ) { | ||
75 | if( shift < 32 ) { | ||
76 | res_nrg = res_nrg - silk_RSHIFT( res_tmp_nrg, shift ); | ||
77 | } | ||
78 | } else { | ||
79 | silk_assert( shift > -32 ); | ||
80 | res_nrg = silk_RSHIFT( res_nrg, -shift ) - res_tmp_nrg; | ||
81 | res_nrg_Q = res_tmp_nrg_Q; | ||
82 | } | ||
83 | |||
84 | /* Convert to NLSFs */ | ||
85 | silk_A2NLSF( NLSF_Q15, a_tmp_Q16, psEncC->predictLPCOrder ); | ||
86 | |||
87 | ALLOC( LPC_res, 2 * subfr_length, opus_int16 ); | ||
88 | |||
89 | /* Search over interpolation indices to find the one with lowest residual energy */ | ||
90 | for( k = 3; k >= 0; k-- ) { | ||
91 | /* Interpolate NLSFs for first half */ | ||
92 | silk_interpolate( NLSF0_Q15, psEncC->prev_NLSFq_Q15, NLSF_Q15, k, psEncC->predictLPCOrder ); | ||
93 | |||
94 | /* Convert to LPC for residual energy evaluation */ | ||
95 | silk_NLSF2A( a_tmp_Q12, NLSF0_Q15, psEncC->predictLPCOrder, psEncC->arch ); | ||
96 | |||
97 | /* Calculate residual energy with NLSF interpolation */ | ||
98 | silk_LPC_analysis_filter( LPC_res, x, a_tmp_Q12, 2 * subfr_length, psEncC->predictLPCOrder, psEncC->arch ); | ||
99 | |||
100 | silk_sum_sqr_shift( &res_nrg0, &rshift0, LPC_res + psEncC->predictLPCOrder, subfr_length - psEncC->predictLPCOrder ); | ||
101 | silk_sum_sqr_shift( &res_nrg1, &rshift1, LPC_res + psEncC->predictLPCOrder + subfr_length, subfr_length - psEncC->predictLPCOrder ); | ||
102 | |||
103 | /* Add subframe energies from first half frame */ | ||
104 | shift = rshift0 - rshift1; | ||
105 | if( shift >= 0 ) { | ||
106 | res_nrg1 = silk_RSHIFT( res_nrg1, shift ); | ||
107 | res_nrg_interp_Q = -rshift0; | ||
108 | } else { | ||
109 | res_nrg0 = silk_RSHIFT( res_nrg0, -shift ); | ||
110 | res_nrg_interp_Q = -rshift1; | ||
111 | } | ||
112 | res_nrg_interp = silk_ADD32( res_nrg0, res_nrg1 ); | ||
113 | |||
114 | /* Compare with first half energy without NLSF interpolation, or best interpolated value so far */ | ||
115 | shift = res_nrg_interp_Q - res_nrg_Q; | ||
116 | if( shift >= 0 ) { | ||
117 | if( silk_RSHIFT( res_nrg_interp, shift ) < res_nrg ) { | ||
118 | isInterpLower = silk_TRUE; | ||
119 | } else { | ||
120 | isInterpLower = silk_FALSE; | ||
121 | } | ||
122 | } else { | ||
123 | if( -shift < 32 ) { | ||
124 | if( res_nrg_interp < silk_RSHIFT( res_nrg, -shift ) ) { | ||
125 | isInterpLower = silk_TRUE; | ||
126 | } else { | ||
127 | isInterpLower = silk_FALSE; | ||
128 | } | ||
129 | } else { | ||
130 | isInterpLower = silk_FALSE; | ||
131 | } | ||
132 | } | ||
133 | |||
134 | /* Determine whether current interpolated NLSFs are best so far */ | ||
135 | if( isInterpLower == silk_TRUE ) { | ||
136 | /* Interpolation has lower residual energy */ | ||
137 | res_nrg = res_nrg_interp; | ||
138 | res_nrg_Q = res_nrg_interp_Q; | ||
139 | psEncC->indices.NLSFInterpCoef_Q2 = (opus_int8)k; | ||
140 | } | ||
141 | } | ||
142 | } | ||
143 | |||
144 | if( psEncC->indices.NLSFInterpCoef_Q2 == 4 ) { | ||
145 | /* NLSF interpolation is currently inactive, calculate NLSFs from full frame AR coefficients */ | ||
146 | silk_A2NLSF( NLSF_Q15, a_Q16, psEncC->predictLPCOrder ); | ||
147 | } | ||
148 | |||
149 | celt_assert( psEncC->indices.NLSFInterpCoef_Q2 == 4 || ( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) ); | ||
150 | RESTORE_STACK; | ||
151 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/find_LTP_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/find_LTP_FIX.c new file mode 100644 index 0000000000..62d4afb250 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/fixed/find_LTP_FIX.c | |||
@@ -0,0 +1,99 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main_FIX.h" | ||
33 | #include "tuning_parameters.h" | ||
34 | |||
35 | void silk_find_LTP_FIX( | ||
36 | opus_int32 XXLTP_Q17[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Correlation matrix */ | ||
37 | opus_int32 xXLTP_Q17[ MAX_NB_SUBFR * LTP_ORDER ], /* O Correlation vector */ | ||
38 | const opus_int16 r_ptr[], /* I Residual signal after LPC */ | ||
39 | const opus_int lag[ MAX_NB_SUBFR ], /* I LTP lags */ | ||
40 | const opus_int subfr_length, /* I Subframe length */ | ||
41 | const opus_int nb_subfr, /* I Number of subframes */ | ||
42 | int arch /* I Run-time architecture */ | ||
43 | ) | ||
44 | { | ||
45 | opus_int i, k, extra_shifts; | ||
46 | opus_int xx_shifts, xX_shifts, XX_shifts; | ||
47 | const opus_int16 *lag_ptr; | ||
48 | opus_int32 *XXLTP_Q17_ptr, *xXLTP_Q17_ptr; | ||
49 | opus_int32 xx, nrg, temp; | ||
50 | |||
51 | xXLTP_Q17_ptr = xXLTP_Q17; | ||
52 | XXLTP_Q17_ptr = XXLTP_Q17; | ||
53 | for( k = 0; k < nb_subfr; k++ ) { | ||
54 | lag_ptr = r_ptr - ( lag[ k ] + LTP_ORDER / 2 ); | ||
55 | |||
56 | silk_sum_sqr_shift( &xx, &xx_shifts, r_ptr, subfr_length + LTP_ORDER ); /* xx in Q( -xx_shifts ) */ | ||
57 | silk_corrMatrix_FIX( lag_ptr, subfr_length, LTP_ORDER, XXLTP_Q17_ptr, &nrg, &XX_shifts, arch ); /* XXLTP_Q17_ptr and nrg in Q( -XX_shifts ) */ | ||
58 | extra_shifts = xx_shifts - XX_shifts; | ||
59 | if( extra_shifts > 0 ) { | ||
60 | /* Shift XX */ | ||
61 | xX_shifts = xx_shifts; | ||
62 | for( i = 0; i < LTP_ORDER * LTP_ORDER; i++ ) { | ||
63 | XXLTP_Q17_ptr[ i ] = silk_RSHIFT32( XXLTP_Q17_ptr[ i ], extra_shifts ); /* Q( -xX_shifts ) */ | ||
64 | } | ||
65 | nrg = silk_RSHIFT32( nrg, extra_shifts ); /* Q( -xX_shifts ) */ | ||
66 | } else if( extra_shifts < 0 ) { | ||
67 | /* Shift xx */ | ||
68 | xX_shifts = XX_shifts; | ||
69 | xx = silk_RSHIFT32( xx, -extra_shifts ); /* Q( -xX_shifts ) */ | ||
70 | } else { | ||
71 | xX_shifts = xx_shifts; | ||
72 | } | ||
73 | silk_corrVector_FIX( lag_ptr, r_ptr, subfr_length, LTP_ORDER, xXLTP_Q17_ptr, xX_shifts, arch ); /* xXLTP_Q17_ptr in Q( -xX_shifts ) */ | ||
74 | |||
75 | /* At this point all correlations are in Q(-xX_shifts) */ | ||
76 | temp = silk_SMLAWB( 1, nrg, SILK_FIX_CONST( LTP_CORR_INV_MAX, 16 ) ); | ||
77 | temp = silk_max( temp, xx ); | ||
78 | TIC(div) | ||
79 | #if 0 | ||
80 | for( i = 0; i < LTP_ORDER * LTP_ORDER; i++ ) { | ||
81 | XXLTP_Q17_ptr[ i ] = silk_DIV32_varQ( XXLTP_Q17_ptr[ i ], temp, 17 ); | ||
82 | } | ||
83 | for( i = 0; i < LTP_ORDER; i++ ) { | ||
84 | xXLTP_Q17_ptr[ i ] = silk_DIV32_varQ( xXLTP_Q17_ptr[ i ], temp, 17 ); | ||
85 | } | ||
86 | #else | ||
87 | for( i = 0; i < LTP_ORDER * LTP_ORDER; i++ ) { | ||
88 | XXLTP_Q17_ptr[ i ] = (opus_int32)( silk_LSHIFT64( (opus_int64)XXLTP_Q17_ptr[ i ], 17 ) / temp ); | ||
89 | } | ||
90 | for( i = 0; i < LTP_ORDER; i++ ) { | ||
91 | xXLTP_Q17_ptr[ i ] = (opus_int32)( silk_LSHIFT64( (opus_int64)xXLTP_Q17_ptr[ i ], 17 ) / temp ); | ||
92 | } | ||
93 | #endif | ||
94 | TOC(div) | ||
95 | r_ptr += subfr_length; | ||
96 | XXLTP_Q17_ptr += LTP_ORDER * LTP_ORDER; | ||
97 | xXLTP_Q17_ptr += LTP_ORDER; | ||
98 | } | ||
99 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/find_pitch_lags_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/find_pitch_lags_FIX.c new file mode 100644 index 0000000000..6c3379f2bb --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/fixed/find_pitch_lags_FIX.c | |||
@@ -0,0 +1,143 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main_FIX.h" | ||
33 | #include "stack_alloc.h" | ||
34 | #include "tuning_parameters.h" | ||
35 | |||
36 | /* Find pitch lags */ | ||
37 | void silk_find_pitch_lags_FIX( | ||
38 | silk_encoder_state_FIX *psEnc, /* I/O encoder state */ | ||
39 | silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */ | ||
40 | opus_int16 res[], /* O residual */ | ||
41 | const opus_int16 x[], /* I Speech signal */ | ||
42 | int arch /* I Run-time architecture */ | ||
43 | ) | ||
44 | { | ||
45 | opus_int buf_len, i, scale; | ||
46 | opus_int32 thrhld_Q13, res_nrg; | ||
47 | const opus_int16 *x_ptr; | ||
48 | VARDECL( opus_int16, Wsig ); | ||
49 | opus_int16 *Wsig_ptr; | ||
50 | opus_int32 auto_corr[ MAX_FIND_PITCH_LPC_ORDER + 1 ]; | ||
51 | opus_int16 rc_Q15[ MAX_FIND_PITCH_LPC_ORDER ]; | ||
52 | opus_int32 A_Q24[ MAX_FIND_PITCH_LPC_ORDER ]; | ||
53 | opus_int16 A_Q12[ MAX_FIND_PITCH_LPC_ORDER ]; | ||
54 | SAVE_STACK; | ||
55 | |||
56 | /******************************************/ | ||
57 | /* Set up buffer lengths etc based on Fs */ | ||
58 | /******************************************/ | ||
59 | buf_len = psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + psEnc->sCmn.ltp_mem_length; | ||
60 | |||
61 | /* Safety check */ | ||
62 | celt_assert( buf_len >= psEnc->sCmn.pitch_LPC_win_length ); | ||
63 | |||
64 | /*************************************/ | ||
65 | /* Estimate LPC AR coefficients */ | ||
66 | /*************************************/ | ||
67 | |||
68 | /* Calculate windowed signal */ | ||
69 | |||
70 | ALLOC( Wsig, psEnc->sCmn.pitch_LPC_win_length, opus_int16 ); | ||
71 | |||
72 | /* First LA_LTP samples */ | ||
73 | x_ptr = x + buf_len - psEnc->sCmn.pitch_LPC_win_length; | ||
74 | Wsig_ptr = Wsig; | ||
75 | silk_apply_sine_window( Wsig_ptr, x_ptr, 1, psEnc->sCmn.la_pitch ); | ||
76 | |||
77 | /* Middle un - windowed samples */ | ||
78 | Wsig_ptr += psEnc->sCmn.la_pitch; | ||
79 | x_ptr += psEnc->sCmn.la_pitch; | ||
80 | silk_memcpy( Wsig_ptr, x_ptr, ( psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 ) ) * sizeof( opus_int16 ) ); | ||
81 | |||
82 | /* Last LA_LTP samples */ | ||
83 | Wsig_ptr += psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 ); | ||
84 | x_ptr += psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 ); | ||
85 | silk_apply_sine_window( Wsig_ptr, x_ptr, 2, psEnc->sCmn.la_pitch ); | ||
86 | |||
87 | /* Calculate autocorrelation sequence */ | ||
88 | silk_autocorr( auto_corr, &scale, Wsig, psEnc->sCmn.pitch_LPC_win_length, psEnc->sCmn.pitchEstimationLPCOrder + 1, arch ); | ||
89 | |||
90 | /* Add white noise, as fraction of energy */ | ||
91 | auto_corr[ 0 ] = silk_SMLAWB( auto_corr[ 0 ], auto_corr[ 0 ], SILK_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) ) + 1; | ||
92 | |||
93 | /* Calculate the reflection coefficients using schur */ | ||
94 | res_nrg = silk_schur( rc_Q15, auto_corr, psEnc->sCmn.pitchEstimationLPCOrder ); | ||
95 | |||
96 | /* Prediction gain */ | ||
97 | psEncCtrl->predGain_Q16 = silk_DIV32_varQ( auto_corr[ 0 ], silk_max_int( res_nrg, 1 ), 16 ); | ||
98 | |||
99 | /* Convert reflection coefficients to prediction coefficients */ | ||
100 | silk_k2a( A_Q24, rc_Q15, psEnc->sCmn.pitchEstimationLPCOrder ); | ||
101 | |||
102 | /* Convert From 32 bit Q24 to 16 bit Q12 coefs */ | ||
103 | for( i = 0; i < psEnc->sCmn.pitchEstimationLPCOrder; i++ ) { | ||
104 | A_Q12[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT( A_Q24[ i ], 12 ) ); | ||
105 | } | ||
106 | |||
107 | /* Do BWE */ | ||
108 | silk_bwexpander( A_Q12, psEnc->sCmn.pitchEstimationLPCOrder, SILK_FIX_CONST( FIND_PITCH_BANDWIDTH_EXPANSION, 16 ) ); | ||
109 | |||
110 | /*****************************************/ | ||
111 | /* LPC analysis filtering */ | ||
112 | /*****************************************/ | ||
113 | silk_LPC_analysis_filter( res, x, A_Q12, buf_len, psEnc->sCmn.pitchEstimationLPCOrder, psEnc->sCmn.arch ); | ||
114 | |||
115 | if( psEnc->sCmn.indices.signalType != TYPE_NO_VOICE_ACTIVITY && psEnc->sCmn.first_frame_after_reset == 0 ) { | ||
116 | /* Threshold for pitch estimator */ | ||
117 | thrhld_Q13 = SILK_FIX_CONST( 0.6, 13 ); | ||
118 | thrhld_Q13 = silk_SMLABB( thrhld_Q13, SILK_FIX_CONST( -0.004, 13 ), psEnc->sCmn.pitchEstimationLPCOrder ); | ||
119 | thrhld_Q13 = silk_SMLAWB( thrhld_Q13, SILK_FIX_CONST( -0.1, 21 ), psEnc->sCmn.speech_activity_Q8 ); | ||
120 | thrhld_Q13 = silk_SMLABB( thrhld_Q13, SILK_FIX_CONST( -0.15, 13 ), silk_RSHIFT( psEnc->sCmn.prevSignalType, 1 ) ); | ||
121 | thrhld_Q13 = silk_SMLAWB( thrhld_Q13, SILK_FIX_CONST( -0.1, 14 ), psEnc->sCmn.input_tilt_Q15 ); | ||
122 | thrhld_Q13 = silk_SAT16( thrhld_Q13 ); | ||
123 | |||
124 | /*****************************************/ | ||
125 | /* Call pitch estimator */ | ||
126 | /*****************************************/ | ||
127 | if( silk_pitch_analysis_core( res, psEncCtrl->pitchL, &psEnc->sCmn.indices.lagIndex, &psEnc->sCmn.indices.contourIndex, | ||
128 | &psEnc->LTPCorr_Q15, psEnc->sCmn.prevLag, psEnc->sCmn.pitchEstimationThreshold_Q16, | ||
129 | (opus_int)thrhld_Q13, psEnc->sCmn.fs_kHz, psEnc->sCmn.pitchEstimationComplexity, psEnc->sCmn.nb_subfr, | ||
130 | psEnc->sCmn.arch) == 0 ) | ||
131 | { | ||
132 | psEnc->sCmn.indices.signalType = TYPE_VOICED; | ||
133 | } else { | ||
134 | psEnc->sCmn.indices.signalType = TYPE_UNVOICED; | ||
135 | } | ||
136 | } else { | ||
137 | silk_memset( psEncCtrl->pitchL, 0, sizeof( psEncCtrl->pitchL ) ); | ||
138 | psEnc->sCmn.indices.lagIndex = 0; | ||
139 | psEnc->sCmn.indices.contourIndex = 0; | ||
140 | psEnc->LTPCorr_Q15 = 0; | ||
141 | } | ||
142 | RESTORE_STACK; | ||
143 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/find_pred_coefs_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/find_pred_coefs_FIX.c new file mode 100644 index 0000000000..606d863347 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/fixed/find_pred_coefs_FIX.c | |||
@@ -0,0 +1,145 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main_FIX.h" | ||
33 | #include "stack_alloc.h" | ||
34 | |||
35 | void silk_find_pred_coefs_FIX( | ||
36 | silk_encoder_state_FIX *psEnc, /* I/O encoder state */ | ||
37 | silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */ | ||
38 | const opus_int16 res_pitch[], /* I Residual from pitch analysis */ | ||
39 | const opus_int16 x[], /* I Speech signal */ | ||
40 | opus_int condCoding /* I The type of conditional coding to use */ | ||
41 | ) | ||
42 | { | ||
43 | opus_int i; | ||
44 | opus_int32 invGains_Q16[ MAX_NB_SUBFR ], local_gains[ MAX_NB_SUBFR ]; | ||
45 | opus_int16 NLSF_Q15[ MAX_LPC_ORDER ]; | ||
46 | const opus_int16 *x_ptr; | ||
47 | opus_int16 *x_pre_ptr; | ||
48 | VARDECL( opus_int16, LPC_in_pre ); | ||
49 | opus_int32 min_gain_Q16, minInvGain_Q30; | ||
50 | SAVE_STACK; | ||
51 | |||
52 | /* weighting for weighted least squares */ | ||
53 | min_gain_Q16 = silk_int32_MAX >> 6; | ||
54 | for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { | ||
55 | min_gain_Q16 = silk_min( min_gain_Q16, psEncCtrl->Gains_Q16[ i ] ); | ||
56 | } | ||
57 | for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { | ||
58 | /* Divide to Q16 */ | ||
59 | silk_assert( psEncCtrl->Gains_Q16[ i ] > 0 ); | ||
60 | /* Invert and normalize gains, and ensure that maximum invGains_Q16 is within range of a 16 bit int */ | ||
61 | invGains_Q16[ i ] = silk_DIV32_varQ( min_gain_Q16, psEncCtrl->Gains_Q16[ i ], 16 - 2 ); | ||
62 | |||
63 | /* Limit inverse */ | ||
64 | invGains_Q16[ i ] = silk_max( invGains_Q16[ i ], 100 ); | ||
65 | |||
66 | /* Square the inverted gains */ | ||
67 | silk_assert( invGains_Q16[ i ] == silk_SAT16( invGains_Q16[ i ] ) ); | ||
68 | |||
69 | /* Invert the inverted and normalized gains */ | ||
70 | local_gains[ i ] = silk_DIV32( ( (opus_int32)1 << 16 ), invGains_Q16[ i ] ); | ||
71 | } | ||
72 | |||
73 | ALLOC( LPC_in_pre, | ||
74 | psEnc->sCmn.nb_subfr * psEnc->sCmn.predictLPCOrder | ||
75 | + psEnc->sCmn.frame_length, opus_int16 ); | ||
76 | if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { | ||
77 | VARDECL( opus_int32, xXLTP_Q17 ); | ||
78 | VARDECL( opus_int32, XXLTP_Q17 ); | ||
79 | |||
80 | /**********/ | ||
81 | /* VOICED */ | ||
82 | /**********/ | ||
83 | celt_assert( psEnc->sCmn.ltp_mem_length - psEnc->sCmn.predictLPCOrder >= psEncCtrl->pitchL[ 0 ] + LTP_ORDER / 2 ); | ||
84 | |||
85 | ALLOC( xXLTP_Q17, psEnc->sCmn.nb_subfr * LTP_ORDER, opus_int32 ); | ||
86 | ALLOC( XXLTP_Q17, psEnc->sCmn.nb_subfr * LTP_ORDER * LTP_ORDER, opus_int32 ); | ||
87 | |||
88 | /* LTP analysis */ | ||
89 | silk_find_LTP_FIX( XXLTP_Q17, xXLTP_Q17, res_pitch, | ||
90 | psEncCtrl->pitchL, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.arch ); | ||
91 | |||
92 | /* Quantize LTP gain parameters */ | ||
93 | silk_quant_LTP_gains( psEncCtrl->LTPCoef_Q14, psEnc->sCmn.indices.LTPIndex, &psEnc->sCmn.indices.PERIndex, | ||
94 | &psEnc->sCmn.sum_log_gain_Q7, &psEncCtrl->LTPredCodGain_Q7, XXLTP_Q17, xXLTP_Q17, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.arch ); | ||
95 | |||
96 | /* Control LTP scaling */ | ||
97 | silk_LTP_scale_ctrl_FIX( psEnc, psEncCtrl, condCoding ); | ||
98 | |||
99 | /* Create LTP residual */ | ||
100 | silk_LTP_analysis_filter_FIX( LPC_in_pre, x - psEnc->sCmn.predictLPCOrder, psEncCtrl->LTPCoef_Q14, | ||
101 | psEncCtrl->pitchL, invGains_Q16, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder ); | ||
102 | |||
103 | } else { | ||
104 | /************/ | ||
105 | /* UNVOICED */ | ||
106 | /************/ | ||
107 | /* Create signal with prepended subframes, scaled by inverse gains */ | ||
108 | x_ptr = x - psEnc->sCmn.predictLPCOrder; | ||
109 | x_pre_ptr = LPC_in_pre; | ||
110 | for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { | ||
111 | silk_scale_copy_vector16( x_pre_ptr, x_ptr, invGains_Q16[ i ], | ||
112 | psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder ); | ||
113 | x_pre_ptr += psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder; | ||
114 | x_ptr += psEnc->sCmn.subfr_length; | ||
115 | } | ||
116 | |||
117 | silk_memset( psEncCtrl->LTPCoef_Q14, 0, psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( opus_int16 ) ); | ||
118 | psEncCtrl->LTPredCodGain_Q7 = 0; | ||
119 | psEnc->sCmn.sum_log_gain_Q7 = 0; | ||
120 | } | ||
121 | |||
122 | /* Limit on total predictive coding gain */ | ||
123 | if( psEnc->sCmn.first_frame_after_reset ) { | ||
124 | minInvGain_Q30 = SILK_FIX_CONST( 1.0f / MAX_PREDICTION_POWER_GAIN_AFTER_RESET, 30 ); | ||
125 | } else { | ||
126 | minInvGain_Q30 = silk_log2lin( silk_SMLAWB( 16 << 7, (opus_int32)psEncCtrl->LTPredCodGain_Q7, SILK_FIX_CONST( 1.0 / 3, 16 ) ) ); /* Q16 */ | ||
127 | minInvGain_Q30 = silk_DIV32_varQ( minInvGain_Q30, | ||
128 | silk_SMULWW( SILK_FIX_CONST( MAX_PREDICTION_POWER_GAIN, 0 ), | ||
129 | silk_SMLAWB( SILK_FIX_CONST( 0.25, 18 ), SILK_FIX_CONST( 0.75, 18 ), psEncCtrl->coding_quality_Q14 ) ), 14 ); | ||
130 | } | ||
131 | |||
132 | /* LPC_in_pre contains the LTP-filtered input for voiced, and the unfiltered input for unvoiced */ | ||
133 | silk_find_LPC_FIX( &psEnc->sCmn, NLSF_Q15, LPC_in_pre, minInvGain_Q30 ); | ||
134 | |||
135 | /* Quantize LSFs */ | ||
136 | silk_process_NLSFs( &psEnc->sCmn, psEncCtrl->PredCoef_Q12, NLSF_Q15, psEnc->sCmn.prev_NLSFq_Q15 ); | ||
137 | |||
138 | /* Calculate residual energy using quantized LPC coefficients */ | ||
139 | silk_residual_energy_FIX( psEncCtrl->ResNrg, psEncCtrl->ResNrgQ, LPC_in_pre, psEncCtrl->PredCoef_Q12, local_gains, | ||
140 | psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder, psEnc->sCmn.arch ); | ||
141 | |||
142 | /* Copy to prediction struct for use in next frame for interpolation */ | ||
143 | silk_memcpy( psEnc->sCmn.prev_NLSFq_Q15, NLSF_Q15, sizeof( psEnc->sCmn.prev_NLSFq_Q15 ) ); | ||
144 | RESTORE_STACK; | ||
145 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/k2a_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/k2a_FIX.c new file mode 100644 index 0000000000..549f6eadaa --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/fixed/k2a_FIX.c | |||
@@ -0,0 +1,54 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "SigProc_FIX.h" | ||
33 | |||
34 | /* Step up function, converts reflection coefficients to prediction coefficients */ | ||
35 | void silk_k2a( | ||
36 | opus_int32 *A_Q24, /* O Prediction coefficients [order] Q24 */ | ||
37 | const opus_int16 *rc_Q15, /* I Reflection coefficients [order] Q15 */ | ||
38 | const opus_int32 order /* I Prediction order */ | ||
39 | ) | ||
40 | { | ||
41 | opus_int k, n; | ||
42 | opus_int32 rc, tmp1, tmp2; | ||
43 | |||
44 | for( k = 0; k < order; k++ ) { | ||
45 | rc = rc_Q15[ k ]; | ||
46 | for( n = 0; n < (k + 1) >> 1; n++ ) { | ||
47 | tmp1 = A_Q24[ n ]; | ||
48 | tmp2 = A_Q24[ k - n - 1 ]; | ||
49 | A_Q24[ n ] = silk_SMLAWB( tmp1, silk_LSHIFT( tmp2, 1 ), rc ); | ||
50 | A_Q24[ k - n - 1 ] = silk_SMLAWB( tmp2, silk_LSHIFT( tmp1, 1 ), rc ); | ||
51 | } | ||
52 | A_Q24[ k ] = -silk_LSHIFT( (opus_int32)rc_Q15[ k ], 9 ); | ||
53 | } | ||
54 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/k2a_Q16_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/k2a_Q16_FIX.c new file mode 100644 index 0000000000..1595aa6212 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/fixed/k2a_Q16_FIX.c | |||
@@ -0,0 +1,54 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "SigProc_FIX.h" | ||
33 | |||
34 | /* Step up function, converts reflection coefficients to prediction coefficients */ | ||
35 | void silk_k2a_Q16( | ||
36 | opus_int32 *A_Q24, /* O Prediction coefficients [order] Q24 */ | ||
37 | const opus_int32 *rc_Q16, /* I Reflection coefficients [order] Q16 */ | ||
38 | const opus_int32 order /* I Prediction order */ | ||
39 | ) | ||
40 | { | ||
41 | opus_int k, n; | ||
42 | opus_int32 rc, tmp1, tmp2; | ||
43 | |||
44 | for( k = 0; k < order; k++ ) { | ||
45 | rc = rc_Q16[ k ]; | ||
46 | for( n = 0; n < (k + 1) >> 1; n++ ) { | ||
47 | tmp1 = A_Q24[ n ]; | ||
48 | tmp2 = A_Q24[ k - n - 1 ]; | ||
49 | A_Q24[ n ] = silk_SMLAWW( tmp1, tmp2, rc ); | ||
50 | A_Q24[ k - n - 1 ] = silk_SMLAWW( tmp2, tmp1, rc ); | ||
51 | } | ||
52 | A_Q24[ k ] = -silk_LSHIFT( rc, 8 ); | ||
53 | } | ||
54 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/main_FIX.h b/lib/rbcodec/codecs/libopus/silk/fixed/main_FIX.h new file mode 100644 index 0000000000..6d2112e511 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/fixed/main_FIX.h | |||
@@ -0,0 +1,244 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifndef SILK_MAIN_FIX_H | ||
29 | #define SILK_MAIN_FIX_H | ||
30 | |||
31 | #include "SigProc_FIX.h" | ||
32 | #include "structs_FIX.h" | ||
33 | #include "control.h" | ||
34 | #include "main.h" | ||
35 | #include "PLC.h" | ||
36 | #include "debug.h" | ||
37 | #include "entenc.h" | ||
38 | |||
39 | #if ((defined(OPUS_ARM_ASM) && defined(FIXED_POINT)) \ | ||
40 | || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)) | ||
41 | #include "fixed/arm/warped_autocorrelation_FIX_arm.h" | ||
42 | #endif | ||
43 | |||
44 | #ifndef FORCE_CPP_BUILD | ||
45 | #ifdef __cplusplus | ||
46 | extern "C" | ||
47 | { | ||
48 | #endif | ||
49 | #endif | ||
50 | |||
51 | #define silk_encoder_state_Fxx silk_encoder_state_FIX | ||
52 | #define silk_encode_do_VAD_Fxx silk_encode_do_VAD_FIX | ||
53 | #define silk_encode_frame_Fxx silk_encode_frame_FIX | ||
54 | |||
55 | #define QC 10 | ||
56 | #define QS 13 | ||
57 | |||
58 | /*********************/ | ||
59 | /* Encoder Functions */ | ||
60 | /*********************/ | ||
61 | |||
62 | /* High-pass filter with cutoff frequency adaptation based on pitch lag statistics */ | ||
63 | void silk_HP_variable_cutoff( | ||
64 | silk_encoder_state_Fxx state_Fxx[] /* I/O Encoder states */ | ||
65 | ); | ||
66 | |||
67 | /* Encoder main function */ | ||
68 | void silk_encode_do_VAD_FIX( | ||
69 | silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */ | ||
70 | opus_int activity /* I Decision of Opus voice activity detector */ | ||
71 | ); | ||
72 | |||
73 | /* Encoder main function */ | ||
74 | opus_int silk_encode_frame_FIX( | ||
75 | silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */ | ||
76 | opus_int32 *pnBytesOut, /* O Pointer to number of payload bytes; */ | ||
77 | ec_enc *psRangeEnc, /* I/O compressor data structure */ | ||
78 | opus_int condCoding, /* I The type of conditional coding to use */ | ||
79 | opus_int maxBits, /* I If > 0: maximum number of output bits */ | ||
80 | opus_int useCBR /* I Flag to force constant-bitrate operation */ | ||
81 | ); | ||
82 | |||
83 | /* Initializes the Silk encoder state */ | ||
84 | opus_int silk_init_encoder( | ||
85 | silk_encoder_state_Fxx *psEnc, /* I/O Pointer to Silk FIX encoder state */ | ||
86 | int arch /* I Run-time architecture */ | ||
87 | ); | ||
88 | |||
89 | /* Control the Silk encoder */ | ||
90 | opus_int silk_control_encoder( | ||
91 | silk_encoder_state_Fxx *psEnc, /* I/O Pointer to Silk encoder state */ | ||
92 | silk_EncControlStruct *encControl, /* I Control structure */ | ||
93 | const opus_int allow_bw_switch, /* I Flag to allow switching audio bandwidth */ | ||
94 | const opus_int channelNb, /* I Channel number */ | ||
95 | const opus_int force_fs_kHz | ||
96 | ); | ||
97 | |||
98 | /**************************/ | ||
99 | /* Noise shaping analysis */ | ||
100 | /**************************/ | ||
101 | /* Compute noise shaping coefficients and initial gain values */ | ||
102 | void silk_noise_shape_analysis_FIX( | ||
103 | silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */ | ||
104 | silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control FIX */ | ||
105 | const opus_int16 *pitch_res, /* I LPC residual from pitch analysis */ | ||
106 | const opus_int16 *x, /* I Input signal [ frame_length + la_shape ] */ | ||
107 | int arch /* I Run-time architecture */ | ||
108 | ); | ||
109 | |||
110 | /* Autocorrelations for a warped frequency axis */ | ||
111 | void silk_warped_autocorrelation_FIX_c( | ||
112 | opus_int32 *corr, /* O Result [order + 1] */ | ||
113 | opus_int *scale, /* O Scaling of the correlation vector */ | ||
114 | const opus_int16 *input, /* I Input data to correlate */ | ||
115 | const opus_int warping_Q16, /* I Warping coefficient */ | ||
116 | const opus_int length, /* I Length of input */ | ||
117 | const opus_int order /* I Correlation order (even) */ | ||
118 | ); | ||
119 | |||
120 | #if !defined(OVERRIDE_silk_warped_autocorrelation_FIX) | ||
121 | #define silk_warped_autocorrelation_FIX(corr, scale, input, warping_Q16, length, order, arch) \ | ||
122 | ((void)(arch), silk_warped_autocorrelation_FIX_c(corr, scale, input, warping_Q16, length, order)) | ||
123 | #endif | ||
124 | |||
125 | /* Calculation of LTP state scaling */ | ||
126 | void silk_LTP_scale_ctrl_FIX( | ||
127 | silk_encoder_state_FIX *psEnc, /* I/O encoder state */ | ||
128 | silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */ | ||
129 | opus_int condCoding /* I The type of conditional coding to use */ | ||
130 | ); | ||
131 | |||
132 | /**********************************************/ | ||
133 | /* Prediction Analysis */ | ||
134 | /**********************************************/ | ||
135 | /* Find pitch lags */ | ||
136 | void silk_find_pitch_lags_FIX( | ||
137 | silk_encoder_state_FIX *psEnc, /* I/O encoder state */ | ||
138 | silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */ | ||
139 | opus_int16 res[], /* O residual */ | ||
140 | const opus_int16 x[], /* I Speech signal */ | ||
141 | int arch /* I Run-time architecture */ | ||
142 | ); | ||
143 | |||
144 | /* Find LPC and LTP coefficients */ | ||
145 | void silk_find_pred_coefs_FIX( | ||
146 | silk_encoder_state_FIX *psEnc, /* I/O encoder state */ | ||
147 | silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */ | ||
148 | const opus_int16 res_pitch[], /* I Residual from pitch analysis */ | ||
149 | const opus_int16 x[], /* I Speech signal */ | ||
150 | opus_int condCoding /* I The type of conditional coding to use */ | ||
151 | ); | ||
152 | |||
153 | /* LPC analysis */ | ||
154 | void silk_find_LPC_FIX( | ||
155 | silk_encoder_state *psEncC, /* I/O Encoder state */ | ||
156 | opus_int16 NLSF_Q15[], /* O NLSFs */ | ||
157 | const opus_int16 x[], /* I Input signal */ | ||
158 | const opus_int32 minInvGain_Q30 /* I Inverse of max prediction gain */ | ||
159 | ); | ||
160 | |||
161 | /* LTP analysis */ | ||
162 | void silk_find_LTP_FIX( | ||
163 | opus_int32 XXLTP_Q17[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Correlation matrix */ | ||
164 | opus_int32 xXLTP_Q17[ MAX_NB_SUBFR * LTP_ORDER ], /* O Correlation vector */ | ||
165 | const opus_int16 r_lpc[], /* I Residual signal after LPC */ | ||
166 | const opus_int lag[ MAX_NB_SUBFR ], /* I LTP lags */ | ||
167 | const opus_int subfr_length, /* I Subframe length */ | ||
168 | const opus_int nb_subfr, /* I Number of subframes */ | ||
169 | int arch /* I Run-time architecture */ | ||
170 | ); | ||
171 | |||
172 | void silk_LTP_analysis_filter_FIX( | ||
173 | opus_int16 *LTP_res, /* O LTP residual signal of length MAX_NB_SUBFR * ( pre_length + subfr_length ) */ | ||
174 | const opus_int16 *x, /* I Pointer to input signal with at least max( pitchL ) preceding samples */ | ||
175 | const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],/* I LTP_ORDER LTP coefficients for each MAX_NB_SUBFR subframe */ | ||
176 | const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag, one for each subframe */ | ||
177 | const opus_int32 invGains_Q16[ MAX_NB_SUBFR ], /* I Inverse quantization gains, one for each subframe */ | ||
178 | const opus_int subfr_length, /* I Length of each subframe */ | ||
179 | const opus_int nb_subfr, /* I Number of subframes */ | ||
180 | const opus_int pre_length /* I Length of the preceding samples starting at &x[0] for each subframe */ | ||
181 | ); | ||
182 | |||
183 | /* Calculates residual energies of input subframes where all subframes have LPC_order */ | ||
184 | /* of preceding samples */ | ||
185 | void silk_residual_energy_FIX( | ||
186 | opus_int32 nrgs[ MAX_NB_SUBFR ], /* O Residual energy per subframe */ | ||
187 | opus_int nrgsQ[ MAX_NB_SUBFR ], /* O Q value per subframe */ | ||
188 | const opus_int16 x[], /* I Input signal */ | ||
189 | opus_int16 a_Q12[ 2 ][ MAX_LPC_ORDER ], /* I AR coefs for each frame half */ | ||
190 | const opus_int32 gains[ MAX_NB_SUBFR ], /* I Quantization gains */ | ||
191 | const opus_int subfr_length, /* I Subframe length */ | ||
192 | const opus_int nb_subfr, /* I Number of subframes */ | ||
193 | const opus_int LPC_order, /* I LPC order */ | ||
194 | int arch /* I Run-time architecture */ | ||
195 | ); | ||
196 | |||
197 | /* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */ | ||
198 | opus_int32 silk_residual_energy16_covar_FIX( | ||
199 | const opus_int16 *c, /* I Prediction vector */ | ||
200 | const opus_int32 *wXX, /* I Correlation matrix */ | ||
201 | const opus_int32 *wXx, /* I Correlation vector */ | ||
202 | opus_int32 wxx, /* I Signal energy */ | ||
203 | opus_int D, /* I Dimension */ | ||
204 | opus_int cQ /* I Q value for c vector 0 - 15 */ | ||
205 | ); | ||
206 | |||
207 | /* Processing of gains */ | ||
208 | void silk_process_gains_FIX( | ||
209 | silk_encoder_state_FIX *psEnc, /* I/O Encoder state */ | ||
210 | silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control */ | ||
211 | opus_int condCoding /* I The type of conditional coding to use */ | ||
212 | ); | ||
213 | |||
214 | /******************/ | ||
215 | /* Linear Algebra */ | ||
216 | /******************/ | ||
217 | /* Calculates correlation matrix X'*X */ | ||
218 | void silk_corrMatrix_FIX( | ||
219 | const opus_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */ | ||
220 | const opus_int L, /* I Length of vectors */ | ||
221 | const opus_int order, /* I Max lag for correlation */ | ||
222 | opus_int32 *XX, /* O Pointer to X'*X correlation matrix [ order x order ] */ | ||
223 | opus_int32 *nrg, /* O Energy of x vector */ | ||
224 | opus_int *rshifts, /* O Right shifts of correlations */ | ||
225 | int arch /* I Run-time architecture */ | ||
226 | ); | ||
227 | |||
228 | /* Calculates correlation vector X'*t */ | ||
229 | void silk_corrVector_FIX( | ||
230 | const opus_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */ | ||
231 | const opus_int16 *t, /* I Target vector [L] */ | ||
232 | const opus_int L, /* I Length of vectors */ | ||
233 | const opus_int order, /* I Max lag for correlation */ | ||
234 | opus_int32 *Xt, /* O Pointer to X'*t correlation vector [order] */ | ||
235 | const opus_int rshifts, /* I Right shifts of correlations */ | ||
236 | int arch /* I Run-time architecture */ | ||
237 | ); | ||
238 | |||
239 | #ifndef FORCE_CPP_BUILD | ||
240 | #ifdef __cplusplus | ||
241 | } | ||
242 | #endif /* __cplusplus */ | ||
243 | #endif /* FORCE_CPP_BUILD */ | ||
244 | #endif /* SILK_MAIN_FIX_H */ | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/mips/noise_shape_analysis_FIX_mipsr1.h b/lib/rbcodec/codecs/libopus/silk/fixed/mips/noise_shape_analysis_FIX_mipsr1.h new file mode 100644 index 0000000000..3999b5bd09 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/fixed/mips/noise_shape_analysis_FIX_mipsr1.h | |||
@@ -0,0 +1,336 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | |||
29 | /**************************************************************/ | ||
30 | /* Compute noise shaping coefficients and initial gain values */ | ||
31 | /**************************************************************/ | ||
32 | #define OVERRIDE_silk_noise_shape_analysis_FIX | ||
33 | |||
34 | void silk_noise_shape_analysis_FIX( | ||
35 | silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */ | ||
36 | silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control FIX */ | ||
37 | const opus_int16 *pitch_res, /* I LPC residual from pitch analysis */ | ||
38 | const opus_int16 *x, /* I Input signal [ frame_length + la_shape ] */ | ||
39 | int arch /* I Run-time architecture */ | ||
40 | ) | ||
41 | { | ||
42 | silk_shape_state_FIX *psShapeSt = &psEnc->sShape; | ||
43 | opus_int k, i, nSamples, Qnrg, b_Q14, warping_Q16, scale = 0; | ||
44 | opus_int32 SNR_adj_dB_Q7, HarmBoost_Q16, HarmShapeGain_Q16, Tilt_Q16, tmp32; | ||
45 | opus_int32 nrg, pre_nrg_Q30, log_energy_Q7, log_energy_prev_Q7, energy_variation_Q7; | ||
46 | opus_int32 delta_Q16, BWExp1_Q16, BWExp2_Q16, gain_mult_Q16, gain_add_Q16, strength_Q16, b_Q8; | ||
47 | opus_int32 auto_corr[ MAX_SHAPE_LPC_ORDER + 1 ]; | ||
48 | opus_int32 refl_coef_Q16[ MAX_SHAPE_LPC_ORDER ]; | ||
49 | opus_int32 AR1_Q24[ MAX_SHAPE_LPC_ORDER ]; | ||
50 | opus_int32 AR2_Q24[ MAX_SHAPE_LPC_ORDER ]; | ||
51 | VARDECL( opus_int16, x_windowed ); | ||
52 | const opus_int16 *x_ptr, *pitch_res_ptr; | ||
53 | SAVE_STACK; | ||
54 | |||
55 | /* Point to start of first LPC analysis block */ | ||
56 | x_ptr = x - psEnc->sCmn.la_shape; | ||
57 | |||
58 | /****************/ | ||
59 | /* GAIN CONTROL */ | ||
60 | /****************/ | ||
61 | SNR_adj_dB_Q7 = psEnc->sCmn.SNR_dB_Q7; | ||
62 | |||
63 | /* Input quality is the average of the quality in the lowest two VAD bands */ | ||
64 | psEncCtrl->input_quality_Q14 = ( opus_int )silk_RSHIFT( (opus_int32)psEnc->sCmn.input_quality_bands_Q15[ 0 ] | ||
65 | + psEnc->sCmn.input_quality_bands_Q15[ 1 ], 2 ); | ||
66 | |||
67 | /* Coding quality level, between 0.0_Q0 and 1.0_Q0, but in Q14 */ | ||
68 | psEncCtrl->coding_quality_Q14 = silk_RSHIFT( silk_sigm_Q15( silk_RSHIFT_ROUND( SNR_adj_dB_Q7 - | ||
69 | SILK_FIX_CONST( 20.0, 7 ), 4 ) ), 1 ); | ||
70 | |||
71 | /* Reduce coding SNR during low speech activity */ | ||
72 | if( psEnc->sCmn.useCBR == 0 ) { | ||
73 | b_Q8 = SILK_FIX_CONST( 1.0, 8 ) - psEnc->sCmn.speech_activity_Q8; | ||
74 | b_Q8 = silk_SMULWB( silk_LSHIFT( b_Q8, 8 ), b_Q8 ); | ||
75 | SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, | ||
76 | silk_SMULBB( SILK_FIX_CONST( -BG_SNR_DECR_dB, 7 ) >> ( 4 + 1 ), b_Q8 ), /* Q11*/ | ||
77 | silk_SMULWB( SILK_FIX_CONST( 1.0, 14 ) + psEncCtrl->input_quality_Q14, psEncCtrl->coding_quality_Q14 ) ); /* Q12*/ | ||
78 | } | ||
79 | |||
80 | if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { | ||
81 | /* Reduce gains for periodic signals */ | ||
82 | SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, SILK_FIX_CONST( HARM_SNR_INCR_dB, 8 ), psEnc->LTPCorr_Q15 ); | ||
83 | } else { | ||
84 | /* For unvoiced signals and low-quality input, adjust the quality slower than SNR_dB setting */ | ||
85 | SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, | ||
86 | silk_SMLAWB( SILK_FIX_CONST( 6.0, 9 ), -SILK_FIX_CONST( 0.4, 18 ), psEnc->sCmn.SNR_dB_Q7 ), | ||
87 | SILK_FIX_CONST( 1.0, 14 ) - psEncCtrl->input_quality_Q14 ); | ||
88 | } | ||
89 | |||
90 | /*************************/ | ||
91 | /* SPARSENESS PROCESSING */ | ||
92 | /*************************/ | ||
93 | /* Set quantizer offset */ | ||
94 | if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { | ||
95 | /* Initially set to 0; may be overruled in process_gains(..) */ | ||
96 | psEnc->sCmn.indices.quantOffsetType = 0; | ||
97 | psEncCtrl->sparseness_Q8 = 0; | ||
98 | } else { | ||
99 | /* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */ | ||
100 | nSamples = silk_LSHIFT( psEnc->sCmn.fs_kHz, 1 ); | ||
101 | energy_variation_Q7 = 0; | ||
102 | log_energy_prev_Q7 = 0; | ||
103 | pitch_res_ptr = pitch_res; | ||
104 | for( k = 0; k < silk_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2; k++ ) { | ||
105 | silk_sum_sqr_shift( &nrg, &scale, pitch_res_ptr, nSamples ); | ||
106 | nrg += silk_RSHIFT( nSamples, scale ); /* Q(-scale)*/ | ||
107 | |||
108 | log_energy_Q7 = silk_lin2log( nrg ); | ||
109 | if( k > 0 ) { | ||
110 | energy_variation_Q7 += silk_abs( log_energy_Q7 - log_energy_prev_Q7 ); | ||
111 | } | ||
112 | log_energy_prev_Q7 = log_energy_Q7; | ||
113 | pitch_res_ptr += nSamples; | ||
114 | } | ||
115 | |||
116 | psEncCtrl->sparseness_Q8 = silk_RSHIFT( silk_sigm_Q15( silk_SMULWB( energy_variation_Q7 - | ||
117 | SILK_FIX_CONST( 5.0, 7 ), SILK_FIX_CONST( 0.1, 16 ) ) ), 7 ); | ||
118 | |||
119 | /* Set quantization offset depending on sparseness measure */ | ||
120 | if( psEncCtrl->sparseness_Q8 > SILK_FIX_CONST( SPARSENESS_THRESHOLD_QNT_OFFSET, 8 ) ) { | ||
121 | psEnc->sCmn.indices.quantOffsetType = 0; | ||
122 | } else { | ||
123 | psEnc->sCmn.indices.quantOffsetType = 1; | ||
124 | } | ||
125 | |||
126 | /* Increase coding SNR for sparse signals */ | ||
127 | SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, SILK_FIX_CONST( SPARSE_SNR_INCR_dB, 15 ), psEncCtrl->sparseness_Q8 - SILK_FIX_CONST( 0.5, 8 ) ); | ||
128 | } | ||
129 | |||
130 | /*******************************/ | ||
131 | /* Control bandwidth expansion */ | ||
132 | /*******************************/ | ||
133 | /* More BWE for signals with high prediction gain */ | ||
134 | strength_Q16 = silk_SMULWB( psEncCtrl->predGain_Q16, SILK_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) ); | ||
135 | BWExp1_Q16 = BWExp2_Q16 = silk_DIV32_varQ( SILK_FIX_CONST( BANDWIDTH_EXPANSION, 16 ), | ||
136 | silk_SMLAWW( SILK_FIX_CONST( 1.0, 16 ), strength_Q16, strength_Q16 ), 16 ); | ||
137 | delta_Q16 = silk_SMULWB( SILK_FIX_CONST( 1.0, 16 ) - silk_SMULBB( 3, psEncCtrl->coding_quality_Q14 ), | ||
138 | SILK_FIX_CONST( LOW_RATE_BANDWIDTH_EXPANSION_DELTA, 16 ) ); | ||
139 | BWExp1_Q16 = silk_SUB32( BWExp1_Q16, delta_Q16 ); | ||
140 | BWExp2_Q16 = silk_ADD32( BWExp2_Q16, delta_Q16 ); | ||
141 | /* BWExp1 will be applied after BWExp2, so make it relative */ | ||
142 | BWExp1_Q16 = silk_DIV32_16( silk_LSHIFT( BWExp1_Q16, 14 ), silk_RSHIFT( BWExp2_Q16, 2 ) ); | ||
143 | |||
144 | if( psEnc->sCmn.warping_Q16 > 0 ) { | ||
145 | /* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */ | ||
146 | warping_Q16 = silk_SMLAWB( psEnc->sCmn.warping_Q16, (opus_int32)psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( 0.01, 18 ) ); | ||
147 | } else { | ||
148 | warping_Q16 = 0; | ||
149 | } | ||
150 | |||
151 | /********************************************/ | ||
152 | /* Compute noise shaping AR coefs and gains */ | ||
153 | /********************************************/ | ||
154 | ALLOC( x_windowed, psEnc->sCmn.shapeWinLength, opus_int16 ); | ||
155 | for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { | ||
156 | /* Apply window: sine slope followed by flat part followed by cosine slope */ | ||
157 | opus_int shift, slope_part, flat_part; | ||
158 | flat_part = psEnc->sCmn.fs_kHz * 3; | ||
159 | slope_part = silk_RSHIFT( psEnc->sCmn.shapeWinLength - flat_part, 1 ); | ||
160 | |||
161 | silk_apply_sine_window( x_windowed, x_ptr, 1, slope_part ); | ||
162 | shift = slope_part; | ||
163 | silk_memcpy( x_windowed + shift, x_ptr + shift, flat_part * sizeof(opus_int16) ); | ||
164 | shift += flat_part; | ||
165 | silk_apply_sine_window( x_windowed + shift, x_ptr + shift, 2, slope_part ); | ||
166 | |||
167 | /* Update pointer: next LPC analysis block */ | ||
168 | x_ptr += psEnc->sCmn.subfr_length; | ||
169 | |||
170 | if( psEnc->sCmn.warping_Q16 > 0 ) { | ||
171 | /* Calculate warped auto correlation */ | ||
172 | silk_warped_autocorrelation_FIX( auto_corr, &scale, x_windowed, warping_Q16, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder, arch ); | ||
173 | } else { | ||
174 | /* Calculate regular auto correlation */ | ||
175 | silk_autocorr( auto_corr, &scale, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1, arch ); | ||
176 | } | ||
177 | |||
178 | /* Add white noise, as a fraction of energy */ | ||
179 | auto_corr[0] = silk_ADD32( auto_corr[0], silk_max_32( silk_SMULWB( silk_RSHIFT( auto_corr[ 0 ], 4 ), | ||
180 | SILK_FIX_CONST( SHAPE_WHITE_NOISE_FRACTION, 20 ) ), 1 ) ); | ||
181 | |||
182 | /* Calculate the reflection coefficients using schur */ | ||
183 | nrg = silk_schur64( refl_coef_Q16, auto_corr, psEnc->sCmn.shapingLPCOrder ); | ||
184 | silk_assert( nrg >= 0 ); | ||
185 | |||
186 | /* Convert reflection coefficients to prediction coefficients */ | ||
187 | silk_k2a_Q16( AR2_Q24, refl_coef_Q16, psEnc->sCmn.shapingLPCOrder ); | ||
188 | |||
189 | Qnrg = -scale; /* range: -12...30*/ | ||
190 | silk_assert( Qnrg >= -12 ); | ||
191 | silk_assert( Qnrg <= 30 ); | ||
192 | |||
193 | /* Make sure that Qnrg is an even number */ | ||
194 | if( Qnrg & 1 ) { | ||
195 | Qnrg -= 1; | ||
196 | nrg >>= 1; | ||
197 | } | ||
198 | |||
199 | tmp32 = silk_SQRT_APPROX( nrg ); | ||
200 | Qnrg >>= 1; /* range: -6...15*/ | ||
201 | |||
202 | psEncCtrl->Gains_Q16[ k ] = (silk_LSHIFT32( silk_LIMIT( (tmp32), silk_RSHIFT32( silk_int32_MIN, (16 - Qnrg) ), \ | ||
203 | silk_RSHIFT32( silk_int32_MAX, (16 - Qnrg) ) ), (16 - Qnrg) )); | ||
204 | |||
205 | if( psEnc->sCmn.warping_Q16 > 0 ) { | ||
206 | /* Adjust gain for warping */ | ||
207 | gain_mult_Q16 = warped_gain( AR2_Q24, warping_Q16, psEnc->sCmn.shapingLPCOrder ); | ||
208 | silk_assert( psEncCtrl->Gains_Q16[ k ] >= 0 ); | ||
209 | if ( silk_SMULWW( silk_RSHIFT_ROUND( psEncCtrl->Gains_Q16[ k ], 1 ), gain_mult_Q16 ) >= ( silk_int32_MAX >> 1 ) ) { | ||
210 | psEncCtrl->Gains_Q16[ k ] = silk_int32_MAX; | ||
211 | } else { | ||
212 | psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 ); | ||
213 | } | ||
214 | } | ||
215 | |||
216 | /* Bandwidth expansion for synthesis filter shaping */ | ||
217 | silk_bwexpander_32( AR2_Q24, psEnc->sCmn.shapingLPCOrder, BWExp2_Q16 ); | ||
218 | |||
219 | /* Compute noise shaping filter coefficients */ | ||
220 | silk_memcpy( AR1_Q24, AR2_Q24, psEnc->sCmn.shapingLPCOrder * sizeof( opus_int32 ) ); | ||
221 | |||
222 | /* Bandwidth expansion for analysis filter shaping */ | ||
223 | silk_assert( BWExp1_Q16 <= SILK_FIX_CONST( 1.0, 16 ) ); | ||
224 | silk_bwexpander_32( AR1_Q24, psEnc->sCmn.shapingLPCOrder, BWExp1_Q16 ); | ||
225 | |||
226 | /* Ratio of prediction gains, in energy domain */ | ||
227 | pre_nrg_Q30 = silk_LPC_inverse_pred_gain_Q24( AR2_Q24, psEnc->sCmn.shapingLPCOrder, arch ); | ||
228 | nrg = silk_LPC_inverse_pred_gain_Q24( AR1_Q24, psEnc->sCmn.shapingLPCOrder, arch ); | ||
229 | |||
230 | /*psEncCtrl->GainsPre[ k ] = 1.0f - 0.7f * ( 1.0f - pre_nrg / nrg ) = 0.3f + 0.7f * pre_nrg / nrg;*/ | ||
231 | pre_nrg_Q30 = silk_LSHIFT32( silk_SMULWB( pre_nrg_Q30, SILK_FIX_CONST( 0.7, 15 ) ), 1 ); | ||
232 | psEncCtrl->GainsPre_Q14[ k ] = ( opus_int ) SILK_FIX_CONST( 0.3, 14 ) + silk_DIV32_varQ( pre_nrg_Q30, nrg, 14 ); | ||
233 | |||
234 | /* Convert to monic warped prediction coefficients and limit absolute values */ | ||
235 | limit_warped_coefs( AR2_Q24, AR1_Q24, warping_Q16, SILK_FIX_CONST( 3.999, 24 ), psEnc->sCmn.shapingLPCOrder ); | ||
236 | |||
237 | /* Convert from Q24 to Q13 and store in int16 */ | ||
238 | for( i = 0; i < psEnc->sCmn.shapingLPCOrder; i++ ) { | ||
239 | psEncCtrl->AR1_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( AR1_Q24[ i ], 11 ) ); | ||
240 | psEncCtrl->AR2_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( AR2_Q24[ i ], 11 ) ); | ||
241 | } | ||
242 | } | ||
243 | |||
244 | /*****************/ | ||
245 | /* Gain tweaking */ | ||
246 | /*****************/ | ||
247 | /* Increase gains during low speech activity and put lower limit on gains */ | ||
248 | gain_mult_Q16 = silk_log2lin( -silk_SMLAWB( -SILK_FIX_CONST( 16.0, 7 ), SNR_adj_dB_Q7, SILK_FIX_CONST( 0.16, 16 ) ) ); | ||
249 | gain_add_Q16 = silk_log2lin( silk_SMLAWB( SILK_FIX_CONST( 16.0, 7 ), SILK_FIX_CONST( MIN_QGAIN_DB, 7 ), SILK_FIX_CONST( 0.16, 16 ) ) ); | ||
250 | silk_assert( gain_mult_Q16 > 0 ); | ||
251 | for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { | ||
252 | psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 ); | ||
253 | silk_assert( psEncCtrl->Gains_Q16[ k ] >= 0 ); | ||
254 | psEncCtrl->Gains_Q16[ k ] = silk_ADD_POS_SAT32( psEncCtrl->Gains_Q16[ k ], gain_add_Q16 ); | ||
255 | } | ||
256 | |||
257 | gain_mult_Q16 = SILK_FIX_CONST( 1.0, 16 ) + silk_RSHIFT_ROUND( silk_MLA( SILK_FIX_CONST( INPUT_TILT, 26 ), | ||
258 | psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( HIGH_RATE_INPUT_TILT, 12 ) ), 10 ); | ||
259 | for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { | ||
260 | psEncCtrl->GainsPre_Q14[ k ] = silk_SMULWB( gain_mult_Q16, psEncCtrl->GainsPre_Q14[ k ] ); | ||
261 | } | ||
262 | |||
263 | /************************************************/ | ||
264 | /* Control low-frequency shaping and noise tilt */ | ||
265 | /************************************************/ | ||
266 | /* Less low frequency shaping for noisy inputs */ | ||
267 | strength_Q16 = silk_MUL( SILK_FIX_CONST( LOW_FREQ_SHAPING, 4 ), silk_SMLAWB( SILK_FIX_CONST( 1.0, 12 ), | ||
268 | SILK_FIX_CONST( LOW_QUALITY_LOW_FREQ_SHAPING_DECR, 13 ), psEnc->sCmn.input_quality_bands_Q15[ 0 ] - SILK_FIX_CONST( 1.0, 15 ) ) ); | ||
269 | strength_Q16 = silk_RSHIFT( silk_MUL( strength_Q16, psEnc->sCmn.speech_activity_Q8 ), 8 ); | ||
270 | if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { | ||
271 | /* Reduce low frequencies quantization noise for periodic signals, depending on pitch lag */ | ||
272 | /*f = 400; freqz([1, -0.98 + 2e-4 * f], [1, -0.97 + 7e-4 * f], 2^12, Fs); axis([0, 1000, -10, 1])*/ | ||
273 | opus_int fs_kHz_inv = silk_DIV32_16( SILK_FIX_CONST( 0.2, 14 ), psEnc->sCmn.fs_kHz ); | ||
274 | for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { | ||
275 | b_Q14 = fs_kHz_inv + silk_DIV32_16( SILK_FIX_CONST( 3.0, 14 ), psEncCtrl->pitchL[ k ] ); | ||
276 | /* Pack two coefficients in one int32 */ | ||
277 | psEncCtrl->LF_shp_Q14[ k ] = silk_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 - silk_SMULWB( strength_Q16, b_Q14 ), 16 ); | ||
278 | psEncCtrl->LF_shp_Q14[ k ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) ); | ||
279 | } | ||
280 | silk_assert( SILK_FIX_CONST( HARM_HP_NOISE_COEF, 24 ) < SILK_FIX_CONST( 0.5, 24 ) ); /* Guarantees that second argument to SMULWB() is within range of an opus_int16*/ | ||
281 | Tilt_Q16 = - SILK_FIX_CONST( HP_NOISE_COEF, 16 ) - | ||
282 | silk_SMULWB( SILK_FIX_CONST( 1.0, 16 ) - SILK_FIX_CONST( HP_NOISE_COEF, 16 ), | ||
283 | silk_SMULWB( SILK_FIX_CONST( HARM_HP_NOISE_COEF, 24 ), psEnc->sCmn.speech_activity_Q8 ) ); | ||
284 | } else { | ||
285 | b_Q14 = silk_DIV32_16( 21299, psEnc->sCmn.fs_kHz ); /* 1.3_Q0 = 21299_Q14*/ | ||
286 | /* Pack two coefficients in one int32 */ | ||
287 | psEncCtrl->LF_shp_Q14[ 0 ] = silk_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 - | ||
288 | silk_SMULWB( strength_Q16, silk_SMULWB( SILK_FIX_CONST( 0.6, 16 ), b_Q14 ) ), 16 ); | ||
289 | psEncCtrl->LF_shp_Q14[ 0 ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) ); | ||
290 | for( k = 1; k < psEnc->sCmn.nb_subfr; k++ ) { | ||
291 | psEncCtrl->LF_shp_Q14[ k ] = psEncCtrl->LF_shp_Q14[ 0 ]; | ||
292 | } | ||
293 | Tilt_Q16 = -SILK_FIX_CONST( HP_NOISE_COEF, 16 ); | ||
294 | } | ||
295 | |||
296 | /****************************/ | ||
297 | /* HARMONIC SHAPING CONTROL */ | ||
298 | /****************************/ | ||
299 | /* Control boosting of harmonic frequencies */ | ||
300 | HarmBoost_Q16 = silk_SMULWB( silk_SMULWB( SILK_FIX_CONST( 1.0, 17 ) - silk_LSHIFT( psEncCtrl->coding_quality_Q14, 3 ), | ||
301 | psEnc->LTPCorr_Q15 ), SILK_FIX_CONST( LOW_RATE_HARMONIC_BOOST, 16 ) ); | ||
302 | |||
303 | /* More harmonic boost for noisy input signals */ | ||
304 | HarmBoost_Q16 = silk_SMLAWB( HarmBoost_Q16, | ||
305 | SILK_FIX_CONST( 1.0, 16 ) - silk_LSHIFT( psEncCtrl->input_quality_Q14, 2 ), SILK_FIX_CONST( LOW_INPUT_QUALITY_HARMONIC_BOOST, 16 ) ); | ||
306 | |||
307 | if( USE_HARM_SHAPING && psEnc->sCmn.indices.signalType == TYPE_VOICED ) { | ||
308 | /* More harmonic noise shaping for high bitrates or noisy input */ | ||
309 | HarmShapeGain_Q16 = silk_SMLAWB( SILK_FIX_CONST( HARMONIC_SHAPING, 16 ), | ||
310 | SILK_FIX_CONST( 1.0, 16 ) - silk_SMULWB( SILK_FIX_CONST( 1.0, 18 ) - silk_LSHIFT( psEncCtrl->coding_quality_Q14, 4 ), | ||
311 | psEncCtrl->input_quality_Q14 ), SILK_FIX_CONST( HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING, 16 ) ); | ||
312 | |||
313 | /* Less harmonic noise shaping for less periodic signals */ | ||
314 | HarmShapeGain_Q16 = silk_SMULWB( silk_LSHIFT( HarmShapeGain_Q16, 1 ), | ||
315 | silk_SQRT_APPROX( silk_LSHIFT( psEnc->LTPCorr_Q15, 15 ) ) ); | ||
316 | } else { | ||
317 | HarmShapeGain_Q16 = 0; | ||
318 | } | ||
319 | |||
320 | /*************************/ | ||
321 | /* Smooth over subframes */ | ||
322 | /*************************/ | ||
323 | for( k = 0; k < MAX_NB_SUBFR; k++ ) { | ||
324 | psShapeSt->HarmBoost_smth_Q16 = | ||
325 | silk_SMLAWB( psShapeSt->HarmBoost_smth_Q16, HarmBoost_Q16 - psShapeSt->HarmBoost_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) ); | ||
326 | psShapeSt->HarmShapeGain_smth_Q16 = | ||
327 | silk_SMLAWB( psShapeSt->HarmShapeGain_smth_Q16, HarmShapeGain_Q16 - psShapeSt->HarmShapeGain_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) ); | ||
328 | psShapeSt->Tilt_smth_Q16 = | ||
329 | silk_SMLAWB( psShapeSt->Tilt_smth_Q16, Tilt_Q16 - psShapeSt->Tilt_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) ); | ||
330 | |||
331 | psEncCtrl->HarmBoost_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->HarmBoost_smth_Q16, 2 ); | ||
332 | psEncCtrl->HarmShapeGain_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->HarmShapeGain_smth_Q16, 2 ); | ||
333 | psEncCtrl->Tilt_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->Tilt_smth_Q16, 2 ); | ||
334 | } | ||
335 | RESTORE_STACK; | ||
336 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/mips/prefilter_FIX_mipsr1.h b/lib/rbcodec/codecs/libopus/silk/fixed/mips/prefilter_FIX_mipsr1.h new file mode 100644 index 0000000000..21b256885f --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/fixed/mips/prefilter_FIX_mipsr1.h | |||
@@ -0,0 +1,184 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | #ifndef __PREFILTER_FIX_MIPSR1_H__ | ||
28 | #define __PREFILTER_FIX_MIPSR1_H__ | ||
29 | |||
30 | #ifdef HAVE_CONFIG_H | ||
31 | #include "config.h" | ||
32 | #endif | ||
33 | |||
34 | #include "main_FIX.h" | ||
35 | #include "stack_alloc.h" | ||
36 | #include "tuning_parameters.h" | ||
37 | |||
38 | #define OVERRIDE_silk_warped_LPC_analysis_filter_FIX | ||
39 | void silk_warped_LPC_analysis_filter_FIX( | ||
40 | opus_int32 state[], /* I/O State [order + 1] */ | ||
41 | opus_int32 res_Q2[], /* O Residual signal [length] */ | ||
42 | const opus_int16 coef_Q13[], /* I Coefficients [order] */ | ||
43 | const opus_int16 input[], /* I Input signal [length] */ | ||
44 | const opus_int16 lambda_Q16, /* I Warping factor */ | ||
45 | const opus_int length, /* I Length of input signal */ | ||
46 | const opus_int order, /* I Filter order (even) */ | ||
47 | int arch | ||
48 | ) | ||
49 | { | ||
50 | opus_int n, i; | ||
51 | opus_int32 acc_Q11, acc_Q22, tmp1, tmp2, tmp3, tmp4; | ||
52 | opus_int32 state_cur, state_next; | ||
53 | |||
54 | (void)arch; | ||
55 | |||
56 | /* Order must be even */ | ||
57 | /* Length must be even */ | ||
58 | |||
59 | silk_assert( ( order & 1 ) == 0 ); | ||
60 | silk_assert( ( length & 1 ) == 0 ); | ||
61 | |||
62 | for( n = 0; n < length; n+=2 ) { | ||
63 | /* Output of lowpass section */ | ||
64 | tmp2 = silk_SMLAWB( state[ 0 ], state[ 1 ], lambda_Q16 ); | ||
65 | state_cur = silk_LSHIFT( input[ n ], 14 ); | ||
66 | /* Output of allpass section */ | ||
67 | tmp1 = silk_SMLAWB( state[ 1 ], state[ 2 ] - tmp2, lambda_Q16 ); | ||
68 | state_next = tmp2; | ||
69 | acc_Q11 = silk_RSHIFT( order, 1 ); | ||
70 | acc_Q11 = silk_SMLAWB( acc_Q11, tmp2, coef_Q13[ 0 ] ); | ||
71 | |||
72 | |||
73 | /* Output of lowpass section */ | ||
74 | tmp4 = silk_SMLAWB( state_cur, state_next, lambda_Q16 ); | ||
75 | state[ 0 ] = silk_LSHIFT( input[ n+1 ], 14 ); | ||
76 | /* Output of allpass section */ | ||
77 | tmp3 = silk_SMLAWB( state_next, tmp1 - tmp4, lambda_Q16 ); | ||
78 | state[ 1 ] = tmp4; | ||
79 | acc_Q22 = silk_RSHIFT( order, 1 ); | ||
80 | acc_Q22 = silk_SMLAWB( acc_Q22, tmp4, coef_Q13[ 0 ] ); | ||
81 | |||
82 | /* Loop over allpass sections */ | ||
83 | for( i = 2; i < order; i += 2 ) { | ||
84 | /* Output of allpass section */ | ||
85 | tmp2 = silk_SMLAWB( state[ i ], state[ i + 1 ] - tmp1, lambda_Q16 ); | ||
86 | state_cur = tmp1; | ||
87 | acc_Q11 = silk_SMLAWB( acc_Q11, tmp1, coef_Q13[ i - 1 ] ); | ||
88 | /* Output of allpass section */ | ||
89 | tmp1 = silk_SMLAWB( state[ i + 1 ], state[ i + 2 ] - tmp2, lambda_Q16 ); | ||
90 | state_next = tmp2; | ||
91 | acc_Q11 = silk_SMLAWB( acc_Q11, tmp2, coef_Q13[ i ] ); | ||
92 | |||
93 | |||
94 | /* Output of allpass section */ | ||
95 | tmp4 = silk_SMLAWB( state_cur, state_next - tmp3, lambda_Q16 ); | ||
96 | state[ i ] = tmp3; | ||
97 | acc_Q22 = silk_SMLAWB( acc_Q22, tmp3, coef_Q13[ i - 1 ] ); | ||
98 | /* Output of allpass section */ | ||
99 | tmp3 = silk_SMLAWB( state_next, tmp1 - tmp4, lambda_Q16 ); | ||
100 | state[ i + 1 ] = tmp4; | ||
101 | acc_Q22 = silk_SMLAWB( acc_Q22, tmp4, coef_Q13[ i ] ); | ||
102 | } | ||
103 | acc_Q11 = silk_SMLAWB( acc_Q11, tmp1, coef_Q13[ order - 1 ] ); | ||
104 | res_Q2[ n ] = silk_LSHIFT( (opus_int32)input[ n ], 2 ) - silk_RSHIFT_ROUND( acc_Q11, 9 ); | ||
105 | |||
106 | state[ order ] = tmp3; | ||
107 | acc_Q22 = silk_SMLAWB( acc_Q22, tmp3, coef_Q13[ order - 1 ] ); | ||
108 | res_Q2[ n+1 ] = silk_LSHIFT( (opus_int32)input[ n+1 ], 2 ) - silk_RSHIFT_ROUND( acc_Q22, 9 ); | ||
109 | } | ||
110 | } | ||
111 | |||
112 | |||
113 | |||
114 | /* Prefilter for finding Quantizer input signal */ | ||
115 | #define OVERRIDE_silk_prefilt_FIX | ||
116 | static inline void silk_prefilt_FIX( | ||
117 | silk_prefilter_state_FIX *P, /* I/O state */ | ||
118 | opus_int32 st_res_Q12[], /* I short term residual signal */ | ||
119 | opus_int32 xw_Q3[], /* O prefiltered signal */ | ||
120 | opus_int32 HarmShapeFIRPacked_Q12, /* I Harmonic shaping coeficients */ | ||
121 | opus_int Tilt_Q14, /* I Tilt shaping coeficient */ | ||
122 | opus_int32 LF_shp_Q14, /* I Low-frequancy shaping coeficients */ | ||
123 | opus_int lag, /* I Lag for harmonic shaping */ | ||
124 | opus_int length /* I Length of signals */ | ||
125 | ) | ||
126 | { | ||
127 | opus_int i, idx, LTP_shp_buf_idx; | ||
128 | opus_int32 n_LTP_Q12, n_Tilt_Q10, n_LF_Q10; | ||
129 | opus_int32 sLF_MA_shp_Q12, sLF_AR_shp_Q12; | ||
130 | opus_int16 *LTP_shp_buf; | ||
131 | |||
132 | /* To speed up use temp variables instead of using the struct */ | ||
133 | LTP_shp_buf = P->sLTP_shp; | ||
134 | LTP_shp_buf_idx = P->sLTP_shp_buf_idx; | ||
135 | sLF_AR_shp_Q12 = P->sLF_AR_shp_Q12; | ||
136 | sLF_MA_shp_Q12 = P->sLF_MA_shp_Q12; | ||
137 | |||
138 | if( lag > 0 ) { | ||
139 | for( i = 0; i < length; i++ ) { | ||
140 | /* unrolled loop */ | ||
141 | silk_assert( HARM_SHAPE_FIR_TAPS == 3 ); | ||
142 | idx = lag + LTP_shp_buf_idx; | ||
143 | n_LTP_Q12 = silk_SMULBB( LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 - 1) & LTP_MASK ], HarmShapeFIRPacked_Q12 ); | ||
144 | n_LTP_Q12 = silk_SMLABT( n_LTP_Q12, LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 ) & LTP_MASK ], HarmShapeFIRPacked_Q12 ); | ||
145 | n_LTP_Q12 = silk_SMLABB( n_LTP_Q12, LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 + 1) & LTP_MASK ], HarmShapeFIRPacked_Q12 ); | ||
146 | |||
147 | n_Tilt_Q10 = silk_SMULWB( sLF_AR_shp_Q12, Tilt_Q14 ); | ||
148 | n_LF_Q10 = silk_SMLAWB( silk_SMULWT( sLF_AR_shp_Q12, LF_shp_Q14 ), sLF_MA_shp_Q12, LF_shp_Q14 ); | ||
149 | |||
150 | sLF_AR_shp_Q12 = silk_SUB32( st_res_Q12[ i ], silk_LSHIFT( n_Tilt_Q10, 2 ) ); | ||
151 | sLF_MA_shp_Q12 = silk_SUB32( sLF_AR_shp_Q12, silk_LSHIFT( n_LF_Q10, 2 ) ); | ||
152 | |||
153 | LTP_shp_buf_idx = ( LTP_shp_buf_idx - 1 ) & LTP_MASK; | ||
154 | LTP_shp_buf[ LTP_shp_buf_idx ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sLF_MA_shp_Q12, 12 ) ); | ||
155 | |||
156 | xw_Q3[i] = silk_RSHIFT_ROUND( silk_SUB32( sLF_MA_shp_Q12, n_LTP_Q12 ), 9 ); | ||
157 | } | ||
158 | } | ||
159 | else | ||
160 | { | ||
161 | for( i = 0; i < length; i++ ) { | ||
162 | |||
163 | n_LTP_Q12 = 0; | ||
164 | |||
165 | n_Tilt_Q10 = silk_SMULWB( sLF_AR_shp_Q12, Tilt_Q14 ); | ||
166 | n_LF_Q10 = silk_SMLAWB( silk_SMULWT( sLF_AR_shp_Q12, LF_shp_Q14 ), sLF_MA_shp_Q12, LF_shp_Q14 ); | ||
167 | |||
168 | sLF_AR_shp_Q12 = silk_SUB32( st_res_Q12[ i ], silk_LSHIFT( n_Tilt_Q10, 2 ) ); | ||
169 | sLF_MA_shp_Q12 = silk_SUB32( sLF_AR_shp_Q12, silk_LSHIFT( n_LF_Q10, 2 ) ); | ||
170 | |||
171 | LTP_shp_buf_idx = ( LTP_shp_buf_idx - 1 ) & LTP_MASK; | ||
172 | LTP_shp_buf[ LTP_shp_buf_idx ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sLF_MA_shp_Q12, 12 ) ); | ||
173 | |||
174 | xw_Q3[i] = silk_RSHIFT_ROUND( sLF_MA_shp_Q12, 9 ); | ||
175 | } | ||
176 | } | ||
177 | |||
178 | /* Copy temp variable back to state */ | ||
179 | P->sLF_AR_shp_Q12 = sLF_AR_shp_Q12; | ||
180 | P->sLF_MA_shp_Q12 = sLF_MA_shp_Q12; | ||
181 | P->sLTP_shp_buf_idx = LTP_shp_buf_idx; | ||
182 | } | ||
183 | |||
184 | #endif /* __PREFILTER_FIX_MIPSR1_H__ */ | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/mips/warped_autocorrelation_FIX_mipsr1.h b/lib/rbcodec/codecs/libopus/silk/fixed/mips/warped_autocorrelation_FIX_mipsr1.h new file mode 100644 index 0000000000..fcbd96c88d --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/fixed/mips/warped_autocorrelation_FIX_mipsr1.h | |||
@@ -0,0 +1,166 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifndef __WARPED_AUTOCORRELATION_FIX_MIPSR1_H__ | ||
29 | #define __WARPED_AUTOCORRELATION_FIX_MIPSR1_H__ | ||
30 | |||
31 | #ifdef HAVE_CONFIG_H | ||
32 | #include "config.h" | ||
33 | #endif | ||
34 | |||
35 | #include "main_FIX.h" | ||
36 | |||
37 | #undef QC | ||
38 | #define QC 10 | ||
39 | |||
40 | #undef QS | ||
41 | #define QS 14 | ||
42 | |||
43 | /* Autocorrelations for a warped frequency axis */ | ||
44 | #define OVERRIDE_silk_warped_autocorrelation_FIX | ||
45 | void silk_warped_autocorrelation_FIX( | ||
46 | opus_int32 *corr, /* O Result [order + 1] */ | ||
47 | opus_int *scale, /* O Scaling of the correlation vector */ | ||
48 | const opus_int16 *input, /* I Input data to correlate */ | ||
49 | const opus_int warping_Q16, /* I Warping coefficient */ | ||
50 | const opus_int length, /* I Length of input */ | ||
51 | const opus_int order, /* I Correlation order (even) */ | ||
52 | int arch /* I Run-time architecture */ | ||
53 | ) | ||
54 | { | ||
55 | opus_int n, i, lsh; | ||
56 | opus_int32 tmp1_QS=0, tmp2_QS=0, tmp3_QS=0, tmp4_QS=0, tmp5_QS=0, tmp6_QS=0, tmp7_QS=0, tmp8_QS=0, start_1=0, start_2=0, start_3=0; | ||
57 | opus_int32 state_QS[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 }; | ||
58 | opus_int64 corr_QC[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 }; | ||
59 | opus_int64 temp64; | ||
60 | |||
61 | opus_int32 val; | ||
62 | val = 2 * QS - QC; | ||
63 | |||
64 | /* Order must be even */ | ||
65 | silk_assert( ( order & 1 ) == 0 ); | ||
66 | silk_assert( 2 * QS - QC >= 0 ); | ||
67 | |||
68 | /* Loop over samples */ | ||
69 | for( n = 0; n < length; n=n+4 ) { | ||
70 | |||
71 | tmp1_QS = silk_LSHIFT32( (opus_int32)input[ n ], QS ); | ||
72 | start_1 = tmp1_QS; | ||
73 | tmp3_QS = silk_LSHIFT32( (opus_int32)input[ n+1], QS ); | ||
74 | start_2 = tmp3_QS; | ||
75 | tmp5_QS = silk_LSHIFT32( (opus_int32)input[ n+2], QS ); | ||
76 | start_3 = tmp5_QS; | ||
77 | tmp7_QS = silk_LSHIFT32( (opus_int32)input[ n+3], QS ); | ||
78 | |||
79 | /* Loop over allpass sections */ | ||
80 | for( i = 0; i < order; i += 2 ) { | ||
81 | /* Output of allpass section */ | ||
82 | tmp2_QS = silk_SMLAWB( state_QS[ i ], state_QS[ i + 1 ] - tmp1_QS, warping_Q16 ); | ||
83 | corr_QC[ i ] = __builtin_mips_madd( corr_QC[ i ], tmp1_QS, start_1); | ||
84 | |||
85 | tmp4_QS = silk_SMLAWB( tmp1_QS, tmp2_QS - tmp3_QS, warping_Q16 ); | ||
86 | corr_QC[ i ] = __builtin_mips_madd( corr_QC[ i ], tmp3_QS, start_2); | ||
87 | |||
88 | tmp6_QS = silk_SMLAWB( tmp3_QS, tmp4_QS - tmp5_QS, warping_Q16 ); | ||
89 | corr_QC[ i ] = __builtin_mips_madd( corr_QC[ i ], tmp5_QS, start_3); | ||
90 | |||
91 | tmp8_QS = silk_SMLAWB( tmp5_QS, tmp6_QS - tmp7_QS, warping_Q16 ); | ||
92 | state_QS[ i ] = tmp7_QS; | ||
93 | corr_QC[ i ] = __builtin_mips_madd( corr_QC[ i ], tmp7_QS, state_QS[0]); | ||
94 | |||
95 | /* Output of allpass section */ | ||
96 | tmp1_QS = silk_SMLAWB( state_QS[ i + 1 ], state_QS[ i + 2 ] - tmp2_QS, warping_Q16 ); | ||
97 | corr_QC[ i+1 ] = __builtin_mips_madd( corr_QC[ i+1 ], tmp2_QS, start_1); | ||
98 | |||
99 | tmp3_QS = silk_SMLAWB( tmp2_QS, tmp1_QS - tmp4_QS, warping_Q16 ); | ||
100 | corr_QC[ i+1 ] = __builtin_mips_madd( corr_QC[ i+1 ], tmp4_QS, start_2); | ||
101 | |||
102 | tmp5_QS = silk_SMLAWB( tmp4_QS, tmp3_QS - tmp6_QS, warping_Q16 ); | ||
103 | corr_QC[ i+1 ] = __builtin_mips_madd( corr_QC[ i+1 ], tmp6_QS, start_3); | ||
104 | |||
105 | tmp7_QS = silk_SMLAWB( tmp6_QS, tmp5_QS - tmp8_QS, warping_Q16 ); | ||
106 | state_QS[ i + 1 ] = tmp8_QS; | ||
107 | corr_QC[ i+1 ] = __builtin_mips_madd( corr_QC[ i+1 ], tmp8_QS, state_QS[ 0 ]); | ||
108 | |||
109 | } | ||
110 | state_QS[ order ] = tmp7_QS; | ||
111 | |||
112 | corr_QC[ order ] = __builtin_mips_madd( corr_QC[ order ], tmp1_QS, start_1); | ||
113 | corr_QC[ order ] = __builtin_mips_madd( corr_QC[ order ], tmp3_QS, start_2); | ||
114 | corr_QC[ order ] = __builtin_mips_madd( corr_QC[ order ], tmp5_QS, start_3); | ||
115 | corr_QC[ order ] = __builtin_mips_madd( corr_QC[ order ], tmp7_QS, state_QS[ 0 ]); | ||
116 | } | ||
117 | |||
118 | for(;n< length; n++ ) { | ||
119 | |||
120 | tmp1_QS = silk_LSHIFT32( (opus_int32)input[ n ], QS ); | ||
121 | |||
122 | /* Loop over allpass sections */ | ||
123 | for( i = 0; i < order; i += 2 ) { | ||
124 | |||
125 | /* Output of allpass section */ | ||
126 | tmp2_QS = silk_SMLAWB( state_QS[ i ], state_QS[ i + 1 ] - tmp1_QS, warping_Q16 ); | ||
127 | state_QS[ i ] = tmp1_QS; | ||
128 | corr_QC[ i ] = __builtin_mips_madd( corr_QC[ i ], tmp1_QS, state_QS[ 0 ]); | ||
129 | |||
130 | /* Output of allpass section */ | ||
131 | tmp1_QS = silk_SMLAWB( state_QS[ i + 1 ], state_QS[ i + 2 ] - tmp2_QS, warping_Q16 ); | ||
132 | state_QS[ i + 1 ] = tmp2_QS; | ||
133 | corr_QC[ i+1 ] = __builtin_mips_madd( corr_QC[ i+1 ], tmp2_QS, state_QS[ 0 ]); | ||
134 | } | ||
135 | state_QS[ order ] = tmp1_QS; | ||
136 | corr_QC[ order ] = __builtin_mips_madd( corr_QC[ order ], tmp1_QS, state_QS[ 0 ]); | ||
137 | } | ||
138 | |||
139 | temp64 = corr_QC[ 0 ]; | ||
140 | temp64 = __builtin_mips_shilo(temp64, val); | ||
141 | |||
142 | lsh = silk_CLZ64( temp64 ) - 35; | ||
143 | lsh = silk_LIMIT( lsh, -12 - QC, 30 - QC ); | ||
144 | *scale = -( QC + lsh ); | ||
145 | silk_assert( *scale >= -30 && *scale <= 12 ); | ||
146 | if( lsh >= 0 ) { | ||
147 | for( i = 0; i < order + 1; i++ ) { | ||
148 | temp64 = corr_QC[ i ]; | ||
149 | //temp64 = __builtin_mips_shilo(temp64, val); | ||
150 | temp64 = (val >= 0) ? (temp64 >> val) : (temp64 << -val); | ||
151 | corr[ i ] = (opus_int32)silk_CHECK_FIT32( __builtin_mips_shilo( temp64, -lsh ) ); | ||
152 | } | ||
153 | } else { | ||
154 | for( i = 0; i < order + 1; i++ ) { | ||
155 | temp64 = corr_QC[ i ]; | ||
156 | //temp64 = __builtin_mips_shilo(temp64, val); | ||
157 | temp64 = (val >= 0) ? (temp64 >> val) : (temp64 << -val); | ||
158 | corr[ i ] = (opus_int32)silk_CHECK_FIT32( __builtin_mips_shilo( temp64, -lsh ) ); | ||
159 | } | ||
160 | } | ||
161 | |||
162 | corr_QC[ 0 ] = __builtin_mips_shilo(corr_QC[ 0 ], val); | ||
163 | |||
164 | silk_assert( corr_QC[ 0 ] >= 0 ); /* If breaking, decrease QC*/ | ||
165 | } | ||
166 | #endif /* __WARPED_AUTOCORRELATION_FIX_MIPSR1_H__ */ | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/noise_shape_analysis_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/noise_shape_analysis_FIX.c new file mode 100644 index 0000000000..85fea0bf09 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/fixed/noise_shape_analysis_FIX.c | |||
@@ -0,0 +1,407 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main_FIX.h" | ||
33 | #include "stack_alloc.h" | ||
34 | #include "tuning_parameters.h" | ||
35 | |||
36 | /* Compute gain to make warped filter coefficients have a zero mean log frequency response on a */ | ||
37 | /* non-warped frequency scale. (So that it can be implemented with a minimum-phase monic filter.) */ | ||
38 | /* Note: A monic filter is one with the first coefficient equal to 1.0. In Silk we omit the first */ | ||
39 | /* coefficient in an array of coefficients, for monic filters. */ | ||
40 | static OPUS_INLINE opus_int32 warped_gain( /* gain in Q16*/ | ||
41 | const opus_int32 *coefs_Q24, | ||
42 | opus_int lambda_Q16, | ||
43 | opus_int order | ||
44 | ) { | ||
45 | opus_int i; | ||
46 | opus_int32 gain_Q24; | ||
47 | |||
48 | lambda_Q16 = -lambda_Q16; | ||
49 | gain_Q24 = coefs_Q24[ order - 1 ]; | ||
50 | for( i = order - 2; i >= 0; i-- ) { | ||
51 | gain_Q24 = silk_SMLAWB( coefs_Q24[ i ], gain_Q24, lambda_Q16 ); | ||
52 | } | ||
53 | gain_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), gain_Q24, -lambda_Q16 ); | ||
54 | return silk_INVERSE32_varQ( gain_Q24, 40 ); | ||
55 | } | ||
56 | |||
57 | /* Convert warped filter coefficients to monic pseudo-warped coefficients and limit maximum */ | ||
58 | /* amplitude of monic warped coefficients by using bandwidth expansion on the true coefficients */ | ||
59 | static OPUS_INLINE void limit_warped_coefs( | ||
60 | opus_int32 *coefs_Q24, | ||
61 | opus_int lambda_Q16, | ||
62 | opus_int32 limit_Q24, | ||
63 | opus_int order | ||
64 | ) { | ||
65 | opus_int i, iter, ind = 0; | ||
66 | opus_int32 tmp, maxabs_Q24, chirp_Q16, gain_Q16; | ||
67 | opus_int32 nom_Q16, den_Q24; | ||
68 | opus_int32 limit_Q20, maxabs_Q20; | ||
69 | |||
70 | /* Convert to monic coefficients */ | ||
71 | lambda_Q16 = -lambda_Q16; | ||
72 | for( i = order - 1; i > 0; i-- ) { | ||
73 | coefs_Q24[ i - 1 ] = silk_SMLAWB( coefs_Q24[ i - 1 ], coefs_Q24[ i ], lambda_Q16 ); | ||
74 | } | ||
75 | lambda_Q16 = -lambda_Q16; | ||
76 | nom_Q16 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 16 ), -(opus_int32)lambda_Q16, lambda_Q16 ); | ||
77 | den_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_Q24[ 0 ], lambda_Q16 ); | ||
78 | gain_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 ); | ||
79 | for( i = 0; i < order; i++ ) { | ||
80 | coefs_Q24[ i ] = silk_SMULWW( gain_Q16, coefs_Q24[ i ] ); | ||
81 | } | ||
82 | limit_Q20 = silk_RSHIFT(limit_Q24, 4); | ||
83 | for( iter = 0; iter < 10; iter++ ) { | ||
84 | /* Find maximum absolute value */ | ||
85 | maxabs_Q24 = -1; | ||
86 | for( i = 0; i < order; i++ ) { | ||
87 | tmp = silk_abs_int32( coefs_Q24[ i ] ); | ||
88 | if( tmp > maxabs_Q24 ) { | ||
89 | maxabs_Q24 = tmp; | ||
90 | ind = i; | ||
91 | } | ||
92 | } | ||
93 | /* Use Q20 to avoid any overflow when multiplying by (ind + 1) later. */ | ||
94 | maxabs_Q20 = silk_RSHIFT(maxabs_Q24, 4); | ||
95 | if( maxabs_Q20 <= limit_Q20 ) { | ||
96 | /* Coefficients are within range - done */ | ||
97 | return; | ||
98 | } | ||
99 | |||
100 | /* Convert back to true warped coefficients */ | ||
101 | for( i = 1; i < order; i++ ) { | ||
102 | coefs_Q24[ i - 1 ] = silk_SMLAWB( coefs_Q24[ i - 1 ], coefs_Q24[ i ], lambda_Q16 ); | ||
103 | } | ||
104 | gain_Q16 = silk_INVERSE32_varQ( gain_Q16, 32 ); | ||
105 | for( i = 0; i < order; i++ ) { | ||
106 | coefs_Q24[ i ] = silk_SMULWW( gain_Q16, coefs_Q24[ i ] ); | ||
107 | } | ||
108 | |||
109 | /* Apply bandwidth expansion */ | ||
110 | chirp_Q16 = SILK_FIX_CONST( 0.99, 16 ) - silk_DIV32_varQ( | ||
111 | silk_SMULWB( maxabs_Q20 - limit_Q20, silk_SMLABB( SILK_FIX_CONST( 0.8, 10 ), SILK_FIX_CONST( 0.1, 10 ), iter ) ), | ||
112 | silk_MUL( maxabs_Q20, ind + 1 ), 22 ); | ||
113 | silk_bwexpander_32( coefs_Q24, order, chirp_Q16 ); | ||
114 | |||
115 | /* Convert to monic warped coefficients */ | ||
116 | lambda_Q16 = -lambda_Q16; | ||
117 | for( i = order - 1; i > 0; i-- ) { | ||
118 | coefs_Q24[ i - 1 ] = silk_SMLAWB( coefs_Q24[ i - 1 ], coefs_Q24[ i ], lambda_Q16 ); | ||
119 | } | ||
120 | lambda_Q16 = -lambda_Q16; | ||
121 | nom_Q16 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 16 ), -(opus_int32)lambda_Q16, lambda_Q16 ); | ||
122 | den_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_Q24[ 0 ], lambda_Q16 ); | ||
123 | gain_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 ); | ||
124 | for( i = 0; i < order; i++ ) { | ||
125 | coefs_Q24[ i ] = silk_SMULWW( gain_Q16, coefs_Q24[ i ] ); | ||
126 | } | ||
127 | } | ||
128 | silk_assert( 0 ); | ||
129 | } | ||
130 | |||
131 | /* Disable MIPS version until it's updated. */ | ||
132 | #if 0 && defined(MIPSr1_ASM) | ||
133 | #include "mips/noise_shape_analysis_FIX_mipsr1.h" | ||
134 | #endif | ||
135 | |||
136 | /**************************************************************/ | ||
137 | /* Compute noise shaping coefficients and initial gain values */ | ||
138 | /**************************************************************/ | ||
139 | #ifndef OVERRIDE_silk_noise_shape_analysis_FIX | ||
140 | void silk_noise_shape_analysis_FIX( | ||
141 | silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */ | ||
142 | silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control FIX */ | ||
143 | const opus_int16 *pitch_res, /* I LPC residual from pitch analysis */ | ||
144 | const opus_int16 *x, /* I Input signal [ frame_length + la_shape ] */ | ||
145 | int arch /* I Run-time architecture */ | ||
146 | ) | ||
147 | { | ||
148 | silk_shape_state_FIX *psShapeSt = &psEnc->sShape; | ||
149 | opus_int k, i, nSamples, nSegs, Qnrg, b_Q14, warping_Q16, scale = 0; | ||
150 | opus_int32 SNR_adj_dB_Q7, HarmShapeGain_Q16, Tilt_Q16, tmp32; | ||
151 | opus_int32 nrg, log_energy_Q7, log_energy_prev_Q7, energy_variation_Q7; | ||
152 | opus_int32 BWExp_Q16, gain_mult_Q16, gain_add_Q16, strength_Q16, b_Q8; | ||
153 | opus_int32 auto_corr[ MAX_SHAPE_LPC_ORDER + 1 ]; | ||
154 | opus_int32 refl_coef_Q16[ MAX_SHAPE_LPC_ORDER ]; | ||
155 | opus_int32 AR_Q24[ MAX_SHAPE_LPC_ORDER ]; | ||
156 | VARDECL( opus_int16, x_windowed ); | ||
157 | const opus_int16 *x_ptr, *pitch_res_ptr; | ||
158 | SAVE_STACK; | ||
159 | |||
160 | /* Point to start of first LPC analysis block */ | ||
161 | x_ptr = x - psEnc->sCmn.la_shape; | ||
162 | |||
163 | /****************/ | ||
164 | /* GAIN CONTROL */ | ||
165 | /****************/ | ||
166 | SNR_adj_dB_Q7 = psEnc->sCmn.SNR_dB_Q7; | ||
167 | |||
168 | /* Input quality is the average of the quality in the lowest two VAD bands */ | ||
169 | psEncCtrl->input_quality_Q14 = ( opus_int )silk_RSHIFT( (opus_int32)psEnc->sCmn.input_quality_bands_Q15[ 0 ] | ||
170 | + psEnc->sCmn.input_quality_bands_Q15[ 1 ], 2 ); | ||
171 | |||
172 | /* Coding quality level, between 0.0_Q0 and 1.0_Q0, but in Q14 */ | ||
173 | psEncCtrl->coding_quality_Q14 = silk_RSHIFT( silk_sigm_Q15( silk_RSHIFT_ROUND( SNR_adj_dB_Q7 - | ||
174 | SILK_FIX_CONST( 20.0, 7 ), 4 ) ), 1 ); | ||
175 | |||
176 | /* Reduce coding SNR during low speech activity */ | ||
177 | if( psEnc->sCmn.useCBR == 0 ) { | ||
178 | b_Q8 = SILK_FIX_CONST( 1.0, 8 ) - psEnc->sCmn.speech_activity_Q8; | ||
179 | b_Q8 = silk_SMULWB( silk_LSHIFT( b_Q8, 8 ), b_Q8 ); | ||
180 | SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, | ||
181 | silk_SMULBB( SILK_FIX_CONST( -BG_SNR_DECR_dB, 7 ) >> ( 4 + 1 ), b_Q8 ), /* Q11*/ | ||
182 | silk_SMULWB( SILK_FIX_CONST( 1.0, 14 ) + psEncCtrl->input_quality_Q14, psEncCtrl->coding_quality_Q14 ) ); /* Q12*/ | ||
183 | } | ||
184 | |||
185 | if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { | ||
186 | /* Reduce gains for periodic signals */ | ||
187 | SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, SILK_FIX_CONST( HARM_SNR_INCR_dB, 8 ), psEnc->LTPCorr_Q15 ); | ||
188 | } else { | ||
189 | /* For unvoiced signals and low-quality input, adjust the quality slower than SNR_dB setting */ | ||
190 | SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, | ||
191 | silk_SMLAWB( SILK_FIX_CONST( 6.0, 9 ), -SILK_FIX_CONST( 0.4, 18 ), psEnc->sCmn.SNR_dB_Q7 ), | ||
192 | SILK_FIX_CONST( 1.0, 14 ) - psEncCtrl->input_quality_Q14 ); | ||
193 | } | ||
194 | |||
195 | /*************************/ | ||
196 | /* SPARSENESS PROCESSING */ | ||
197 | /*************************/ | ||
198 | /* Set quantizer offset */ | ||
199 | if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { | ||
200 | /* Initially set to 0; may be overruled in process_gains(..) */ | ||
201 | psEnc->sCmn.indices.quantOffsetType = 0; | ||
202 | } else { | ||
203 | /* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */ | ||
204 | nSamples = silk_LSHIFT( psEnc->sCmn.fs_kHz, 1 ); | ||
205 | energy_variation_Q7 = 0; | ||
206 | log_energy_prev_Q7 = 0; | ||
207 | pitch_res_ptr = pitch_res; | ||
208 | nSegs = silk_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2; | ||
209 | for( k = 0; k < nSegs; k++ ) { | ||
210 | silk_sum_sqr_shift( &nrg, &scale, pitch_res_ptr, nSamples ); | ||
211 | nrg += silk_RSHIFT( nSamples, scale ); /* Q(-scale)*/ | ||
212 | |||
213 | log_energy_Q7 = silk_lin2log( nrg ); | ||
214 | if( k > 0 ) { | ||
215 | energy_variation_Q7 += silk_abs( log_energy_Q7 - log_energy_prev_Q7 ); | ||
216 | } | ||
217 | log_energy_prev_Q7 = log_energy_Q7; | ||
218 | pitch_res_ptr += nSamples; | ||
219 | } | ||
220 | |||
221 | /* Set quantization offset depending on sparseness measure */ | ||
222 | if( energy_variation_Q7 > SILK_FIX_CONST( ENERGY_VARIATION_THRESHOLD_QNT_OFFSET, 7 ) * (nSegs-1) ) { | ||
223 | psEnc->sCmn.indices.quantOffsetType = 0; | ||
224 | } else { | ||
225 | psEnc->sCmn.indices.quantOffsetType = 1; | ||
226 | } | ||
227 | } | ||
228 | |||
229 | /*******************************/ | ||
230 | /* Control bandwidth expansion */ | ||
231 | /*******************************/ | ||
232 | /* More BWE for signals with high prediction gain */ | ||
233 | strength_Q16 = silk_SMULWB( psEncCtrl->predGain_Q16, SILK_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) ); | ||
234 | BWExp_Q16 = silk_DIV32_varQ( SILK_FIX_CONST( BANDWIDTH_EXPANSION, 16 ), | ||
235 | silk_SMLAWW( SILK_FIX_CONST( 1.0, 16 ), strength_Q16, strength_Q16 ), 16 ); | ||
236 | |||
237 | if( psEnc->sCmn.warping_Q16 > 0 ) { | ||
238 | /* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */ | ||
239 | warping_Q16 = silk_SMLAWB( psEnc->sCmn.warping_Q16, (opus_int32)psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( 0.01, 18 ) ); | ||
240 | } else { | ||
241 | warping_Q16 = 0; | ||
242 | } | ||
243 | |||
244 | /********************************************/ | ||
245 | /* Compute noise shaping AR coefs and gains */ | ||
246 | /********************************************/ | ||
247 | ALLOC( x_windowed, psEnc->sCmn.shapeWinLength, opus_int16 ); | ||
248 | for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { | ||
249 | /* Apply window: sine slope followed by flat part followed by cosine slope */ | ||
250 | opus_int shift, slope_part, flat_part; | ||
251 | flat_part = psEnc->sCmn.fs_kHz * 3; | ||
252 | slope_part = silk_RSHIFT( psEnc->sCmn.shapeWinLength - flat_part, 1 ); | ||
253 | |||
254 | silk_apply_sine_window( x_windowed, x_ptr, 1, slope_part ); | ||
255 | shift = slope_part; | ||
256 | silk_memcpy( x_windowed + shift, x_ptr + shift, flat_part * sizeof(opus_int16) ); | ||
257 | shift += flat_part; | ||
258 | silk_apply_sine_window( x_windowed + shift, x_ptr + shift, 2, slope_part ); | ||
259 | |||
260 | /* Update pointer: next LPC analysis block */ | ||
261 | x_ptr += psEnc->sCmn.subfr_length; | ||
262 | |||
263 | if( psEnc->sCmn.warping_Q16 > 0 ) { | ||
264 | /* Calculate warped auto correlation */ | ||
265 | silk_warped_autocorrelation_FIX( auto_corr, &scale, x_windowed, warping_Q16, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder, arch ); | ||
266 | } else { | ||
267 | /* Calculate regular auto correlation */ | ||
268 | silk_autocorr( auto_corr, &scale, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1, arch ); | ||
269 | } | ||
270 | |||
271 | /* Add white noise, as a fraction of energy */ | ||
272 | auto_corr[0] = silk_ADD32( auto_corr[0], silk_max_32( silk_SMULWB( silk_RSHIFT( auto_corr[ 0 ], 4 ), | ||
273 | SILK_FIX_CONST( SHAPE_WHITE_NOISE_FRACTION, 20 ) ), 1 ) ); | ||
274 | |||
275 | /* Calculate the reflection coefficients using schur */ | ||
276 | nrg = silk_schur64( refl_coef_Q16, auto_corr, psEnc->sCmn.shapingLPCOrder ); | ||
277 | silk_assert( nrg >= 0 ); | ||
278 | |||
279 | /* Convert reflection coefficients to prediction coefficients */ | ||
280 | silk_k2a_Q16( AR_Q24, refl_coef_Q16, psEnc->sCmn.shapingLPCOrder ); | ||
281 | |||
282 | Qnrg = -scale; /* range: -12...30*/ | ||
283 | silk_assert( Qnrg >= -12 ); | ||
284 | silk_assert( Qnrg <= 30 ); | ||
285 | |||
286 | /* Make sure that Qnrg is an even number */ | ||
287 | if( Qnrg & 1 ) { | ||
288 | Qnrg -= 1; | ||
289 | nrg >>= 1; | ||
290 | } | ||
291 | |||
292 | tmp32 = silk_SQRT_APPROX( nrg ); | ||
293 | Qnrg >>= 1; /* range: -6...15*/ | ||
294 | |||
295 | psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT_SAT32( tmp32, 16 - Qnrg ); | ||
296 | |||
297 | if( psEnc->sCmn.warping_Q16 > 0 ) { | ||
298 | /* Adjust gain for warping */ | ||
299 | gain_mult_Q16 = warped_gain( AR_Q24, warping_Q16, psEnc->sCmn.shapingLPCOrder ); | ||
300 | silk_assert( psEncCtrl->Gains_Q16[ k ] > 0 ); | ||
301 | if( psEncCtrl->Gains_Q16[ k ] < SILK_FIX_CONST( 0.25, 16 ) ) { | ||
302 | psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 ); | ||
303 | } else { | ||
304 | psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( silk_RSHIFT_ROUND( psEncCtrl->Gains_Q16[ k ], 1 ), gain_mult_Q16 ); | ||
305 | if ( psEncCtrl->Gains_Q16[ k ] >= ( silk_int32_MAX >> 1 ) ) { | ||
306 | psEncCtrl->Gains_Q16[ k ] = silk_int32_MAX; | ||
307 | } else { | ||
308 | psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT32( psEncCtrl->Gains_Q16[ k ], 1 ); | ||
309 | } | ||
310 | } | ||
311 | silk_assert( psEncCtrl->Gains_Q16[ k ] > 0 ); | ||
312 | } | ||
313 | |||
314 | /* Bandwidth expansion */ | ||
315 | silk_bwexpander_32( AR_Q24, psEnc->sCmn.shapingLPCOrder, BWExp_Q16 ); | ||
316 | |||
317 | if( psEnc->sCmn.warping_Q16 > 0 ) { | ||
318 | /* Convert to monic warped prediction coefficients and limit absolute values */ | ||
319 | limit_warped_coefs( AR_Q24, warping_Q16, SILK_FIX_CONST( 3.999, 24 ), psEnc->sCmn.shapingLPCOrder ); | ||
320 | |||
321 | /* Convert from Q24 to Q13 and store in int16 */ | ||
322 | for( i = 0; i < psEnc->sCmn.shapingLPCOrder; i++ ) { | ||
323 | psEncCtrl->AR_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( AR_Q24[ i ], 11 ) ); | ||
324 | } | ||
325 | } else { | ||
326 | silk_LPC_fit( &psEncCtrl->AR_Q13[ k * MAX_SHAPE_LPC_ORDER ], AR_Q24, 13, 24, psEnc->sCmn.shapingLPCOrder ); | ||
327 | } | ||
328 | } | ||
329 | |||
330 | /*****************/ | ||
331 | /* Gain tweaking */ | ||
332 | /*****************/ | ||
333 | /* Increase gains during low speech activity and put lower limit on gains */ | ||
334 | gain_mult_Q16 = silk_log2lin( -silk_SMLAWB( -SILK_FIX_CONST( 16.0, 7 ), SNR_adj_dB_Q7, SILK_FIX_CONST( 0.16, 16 ) ) ); | ||
335 | gain_add_Q16 = silk_log2lin( silk_SMLAWB( SILK_FIX_CONST( 16.0, 7 ), SILK_FIX_CONST( MIN_QGAIN_DB, 7 ), SILK_FIX_CONST( 0.16, 16 ) ) ); | ||
336 | silk_assert( gain_mult_Q16 > 0 ); | ||
337 | for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { | ||
338 | psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 ); | ||
339 | silk_assert( psEncCtrl->Gains_Q16[ k ] >= 0 ); | ||
340 | psEncCtrl->Gains_Q16[ k ] = silk_ADD_POS_SAT32( psEncCtrl->Gains_Q16[ k ], gain_add_Q16 ); | ||
341 | } | ||
342 | |||
343 | |||
344 | /************************************************/ | ||
345 | /* Control low-frequency shaping and noise tilt */ | ||
346 | /************************************************/ | ||
347 | /* Less low frequency shaping for noisy inputs */ | ||
348 | strength_Q16 = silk_MUL( SILK_FIX_CONST( LOW_FREQ_SHAPING, 4 ), silk_SMLAWB( SILK_FIX_CONST( 1.0, 12 ), | ||
349 | SILK_FIX_CONST( LOW_QUALITY_LOW_FREQ_SHAPING_DECR, 13 ), psEnc->sCmn.input_quality_bands_Q15[ 0 ] - SILK_FIX_CONST( 1.0, 15 ) ) ); | ||
350 | strength_Q16 = silk_RSHIFT( silk_MUL( strength_Q16, psEnc->sCmn.speech_activity_Q8 ), 8 ); | ||
351 | if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { | ||
352 | /* Reduce low frequencies quantization noise for periodic signals, depending on pitch lag */ | ||
353 | /*f = 400; freqz([1, -0.98 + 2e-4 * f], [1, -0.97 + 7e-4 * f], 2^12, Fs); axis([0, 1000, -10, 1])*/ | ||
354 | opus_int fs_kHz_inv = silk_DIV32_16( SILK_FIX_CONST( 0.2, 14 ), psEnc->sCmn.fs_kHz ); | ||
355 | for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { | ||
356 | b_Q14 = fs_kHz_inv + silk_DIV32_16( SILK_FIX_CONST( 3.0, 14 ), psEncCtrl->pitchL[ k ] ); | ||
357 | /* Pack two coefficients in one int32 */ | ||
358 | psEncCtrl->LF_shp_Q14[ k ] = silk_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 - silk_SMULWB( strength_Q16, b_Q14 ), 16 ); | ||
359 | psEncCtrl->LF_shp_Q14[ k ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) ); | ||
360 | } | ||
361 | silk_assert( SILK_FIX_CONST( HARM_HP_NOISE_COEF, 24 ) < SILK_FIX_CONST( 0.5, 24 ) ); /* Guarantees that second argument to SMULWB() is within range of an opus_int16*/ | ||
362 | Tilt_Q16 = - SILK_FIX_CONST( HP_NOISE_COEF, 16 ) - | ||
363 | silk_SMULWB( SILK_FIX_CONST( 1.0, 16 ) - SILK_FIX_CONST( HP_NOISE_COEF, 16 ), | ||
364 | silk_SMULWB( SILK_FIX_CONST( HARM_HP_NOISE_COEF, 24 ), psEnc->sCmn.speech_activity_Q8 ) ); | ||
365 | } else { | ||
366 | b_Q14 = silk_DIV32_16( 21299, psEnc->sCmn.fs_kHz ); /* 1.3_Q0 = 21299_Q14*/ | ||
367 | /* Pack two coefficients in one int32 */ | ||
368 | psEncCtrl->LF_shp_Q14[ 0 ] = silk_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 - | ||
369 | silk_SMULWB( strength_Q16, silk_SMULWB( SILK_FIX_CONST( 0.6, 16 ), b_Q14 ) ), 16 ); | ||
370 | psEncCtrl->LF_shp_Q14[ 0 ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) ); | ||
371 | for( k = 1; k < psEnc->sCmn.nb_subfr; k++ ) { | ||
372 | psEncCtrl->LF_shp_Q14[ k ] = psEncCtrl->LF_shp_Q14[ 0 ]; | ||
373 | } | ||
374 | Tilt_Q16 = -SILK_FIX_CONST( HP_NOISE_COEF, 16 ); | ||
375 | } | ||
376 | |||
377 | /****************************/ | ||
378 | /* HARMONIC SHAPING CONTROL */ | ||
379 | /****************************/ | ||
380 | if( USE_HARM_SHAPING && psEnc->sCmn.indices.signalType == TYPE_VOICED ) { | ||
381 | /* More harmonic noise shaping for high bitrates or noisy input */ | ||
382 | HarmShapeGain_Q16 = silk_SMLAWB( SILK_FIX_CONST( HARMONIC_SHAPING, 16 ), | ||
383 | SILK_FIX_CONST( 1.0, 16 ) - silk_SMULWB( SILK_FIX_CONST( 1.0, 18 ) - silk_LSHIFT( psEncCtrl->coding_quality_Q14, 4 ), | ||
384 | psEncCtrl->input_quality_Q14 ), SILK_FIX_CONST( HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING, 16 ) ); | ||
385 | |||
386 | /* Less harmonic noise shaping for less periodic signals */ | ||
387 | HarmShapeGain_Q16 = silk_SMULWB( silk_LSHIFT( HarmShapeGain_Q16, 1 ), | ||
388 | silk_SQRT_APPROX( silk_LSHIFT( psEnc->LTPCorr_Q15, 15 ) ) ); | ||
389 | } else { | ||
390 | HarmShapeGain_Q16 = 0; | ||
391 | } | ||
392 | |||
393 | /*************************/ | ||
394 | /* Smooth over subframes */ | ||
395 | /*************************/ | ||
396 | for( k = 0; k < MAX_NB_SUBFR; k++ ) { | ||
397 | psShapeSt->HarmShapeGain_smth_Q16 = | ||
398 | silk_SMLAWB( psShapeSt->HarmShapeGain_smth_Q16, HarmShapeGain_Q16 - psShapeSt->HarmShapeGain_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) ); | ||
399 | psShapeSt->Tilt_smth_Q16 = | ||
400 | silk_SMLAWB( psShapeSt->Tilt_smth_Q16, Tilt_Q16 - psShapeSt->Tilt_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) ); | ||
401 | |||
402 | psEncCtrl->HarmShapeGain_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->HarmShapeGain_smth_Q16, 2 ); | ||
403 | psEncCtrl->Tilt_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->Tilt_smth_Q16, 2 ); | ||
404 | } | ||
405 | RESTORE_STACK; | ||
406 | } | ||
407 | #endif /* OVERRIDE_silk_noise_shape_analysis_FIX */ | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/pitch_analysis_core_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/pitch_analysis_core_FIX.c new file mode 100644 index 0000000000..14729046d2 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/fixed/pitch_analysis_core_FIX.c | |||
@@ -0,0 +1,721 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | /*********************************************************** | ||
33 | * Pitch analyser function | ||
34 | ********************************************************** */ | ||
35 | #include "SigProc_FIX.h" | ||
36 | #include "pitch_est_defines.h" | ||
37 | #include "stack_alloc.h" | ||
38 | #include "debug.h" | ||
39 | #include "pitch.h" | ||
40 | |||
41 | #define SCRATCH_SIZE 22 | ||
42 | #define SF_LENGTH_4KHZ ( PE_SUBFR_LENGTH_MS * 4 ) | ||
43 | #define SF_LENGTH_8KHZ ( PE_SUBFR_LENGTH_MS * 8 ) | ||
44 | #define MIN_LAG_4KHZ ( PE_MIN_LAG_MS * 4 ) | ||
45 | #define MIN_LAG_8KHZ ( PE_MIN_LAG_MS * 8 ) | ||
46 | #define MAX_LAG_4KHZ ( PE_MAX_LAG_MS * 4 ) | ||
47 | #define MAX_LAG_8KHZ ( PE_MAX_LAG_MS * 8 - 1 ) | ||
48 | #define CSTRIDE_4KHZ ( MAX_LAG_4KHZ + 1 - MIN_LAG_4KHZ ) | ||
49 | #define CSTRIDE_8KHZ ( MAX_LAG_8KHZ + 3 - ( MIN_LAG_8KHZ - 2 ) ) | ||
50 | #define D_COMP_MIN ( MIN_LAG_8KHZ - 3 ) | ||
51 | #define D_COMP_MAX ( MAX_LAG_8KHZ + 4 ) | ||
52 | #define D_COMP_STRIDE ( D_COMP_MAX - D_COMP_MIN ) | ||
53 | |||
54 | typedef opus_int32 silk_pe_stage3_vals[ PE_NB_STAGE3_LAGS ]; | ||
55 | |||
56 | /************************************************************/ | ||
57 | /* Internally used functions */ | ||
58 | /************************************************************/ | ||
59 | static void silk_P_Ana_calc_corr_st3( | ||
60 | silk_pe_stage3_vals cross_corr_st3[], /* O 3 DIM correlation array */ | ||
61 | const opus_int16 frame[], /* I vector to correlate */ | ||
62 | opus_int start_lag, /* I lag offset to search around */ | ||
63 | opus_int sf_length, /* I length of a 5 ms subframe */ | ||
64 | opus_int nb_subfr, /* I number of subframes */ | ||
65 | opus_int complexity, /* I Complexity setting */ | ||
66 | int arch /* I Run-time architecture */ | ||
67 | ); | ||
68 | |||
69 | static void silk_P_Ana_calc_energy_st3( | ||
70 | silk_pe_stage3_vals energies_st3[], /* O 3 DIM energy array */ | ||
71 | const opus_int16 frame[], /* I vector to calc energy in */ | ||
72 | opus_int start_lag, /* I lag offset to search around */ | ||
73 | opus_int sf_length, /* I length of one 5 ms subframe */ | ||
74 | opus_int nb_subfr, /* I number of subframes */ | ||
75 | opus_int complexity, /* I Complexity setting */ | ||
76 | int arch /* I Run-time architecture */ | ||
77 | ); | ||
78 | |||
79 | /*************************************************************/ | ||
80 | /* FIXED POINT CORE PITCH ANALYSIS FUNCTION */ | ||
81 | /*************************************************************/ | ||
82 | opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0 voiced, 1 unvoiced */ | ||
83 | const opus_int16 *frame_unscaled, /* I Signal of length PE_FRAME_LENGTH_MS*Fs_kHz */ | ||
84 | opus_int *pitch_out, /* O 4 pitch lag values */ | ||
85 | opus_int16 *lagIndex, /* O Lag Index */ | ||
86 | opus_int8 *contourIndex, /* O Pitch contour Index */ | ||
87 | opus_int *LTPCorr_Q15, /* I/O Normalized correlation; input: value from previous frame */ | ||
88 | opus_int prevLag, /* I Last lag of previous frame; set to zero is unvoiced */ | ||
89 | const opus_int32 search_thres1_Q16, /* I First stage threshold for lag candidates 0 - 1 */ | ||
90 | const opus_int search_thres2_Q13, /* I Final threshold for lag candidates 0 - 1 */ | ||
91 | const opus_int Fs_kHz, /* I Sample frequency (kHz) */ | ||
92 | const opus_int complexity, /* I Complexity setting, 0-2, where 2 is highest */ | ||
93 | const opus_int nb_subfr, /* I number of 5 ms subframes */ | ||
94 | int arch /* I Run-time architecture */ | ||
95 | ) | ||
96 | { | ||
97 | VARDECL( opus_int16, frame_8kHz_buf ); | ||
98 | VARDECL( opus_int16, frame_4kHz ); | ||
99 | VARDECL( opus_int16, frame_scaled ); | ||
100 | opus_int32 filt_state[ 6 ]; | ||
101 | const opus_int16 *frame, *frame_8kHz; | ||
102 | opus_int i, k, d, j; | ||
103 | VARDECL( opus_int16, C ); | ||
104 | VARDECL( opus_int32, xcorr32 ); | ||
105 | const opus_int16 *target_ptr, *basis_ptr; | ||
106 | opus_int32 cross_corr, normalizer, energy, energy_basis, energy_target; | ||
107 | opus_int d_srch[ PE_D_SRCH_LENGTH ], Cmax, length_d_srch, length_d_comp, shift; | ||
108 | VARDECL( opus_int16, d_comp ); | ||
109 | opus_int32 sum, threshold, lag_counter; | ||
110 | opus_int CBimax, CBimax_new, CBimax_old, lag, start_lag, end_lag, lag_new; | ||
111 | opus_int32 CC[ PE_NB_CBKS_STAGE2_EXT ], CCmax, CCmax_b, CCmax_new_b, CCmax_new; | ||
112 | VARDECL( silk_pe_stage3_vals, energies_st3 ); | ||
113 | VARDECL( silk_pe_stage3_vals, cross_corr_st3 ); | ||
114 | opus_int frame_length, frame_length_8kHz, frame_length_4kHz; | ||
115 | opus_int sf_length; | ||
116 | opus_int min_lag; | ||
117 | opus_int max_lag; | ||
118 | opus_int32 contour_bias_Q15, diff; | ||
119 | opus_int nb_cbk_search, cbk_size; | ||
120 | opus_int32 delta_lag_log2_sqr_Q7, lag_log2_Q7, prevLag_log2_Q7, prev_lag_bias_Q13; | ||
121 | const opus_int8 *Lag_CB_ptr; | ||
122 | SAVE_STACK; | ||
123 | |||
124 | /* Check for valid sampling frequency */ | ||
125 | celt_assert( Fs_kHz == 8 || Fs_kHz == 12 || Fs_kHz == 16 ); | ||
126 | |||
127 | /* Check for valid complexity setting */ | ||
128 | celt_assert( complexity >= SILK_PE_MIN_COMPLEX ); | ||
129 | celt_assert( complexity <= SILK_PE_MAX_COMPLEX ); | ||
130 | |||
131 | silk_assert( search_thres1_Q16 >= 0 && search_thres1_Q16 <= (1<<16) ); | ||
132 | silk_assert( search_thres2_Q13 >= 0 && search_thres2_Q13 <= (1<<13) ); | ||
133 | |||
134 | /* Set up frame lengths max / min lag for the sampling frequency */ | ||
135 | frame_length = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * Fs_kHz; | ||
136 | frame_length_4kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 4; | ||
137 | frame_length_8kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 8; | ||
138 | sf_length = PE_SUBFR_LENGTH_MS * Fs_kHz; | ||
139 | min_lag = PE_MIN_LAG_MS * Fs_kHz; | ||
140 | max_lag = PE_MAX_LAG_MS * Fs_kHz - 1; | ||
141 | |||
142 | /* Downscale input if necessary */ | ||
143 | silk_sum_sqr_shift( &energy, &shift, frame_unscaled, frame_length ); | ||
144 | shift += 3 - silk_CLZ32( energy ); /* at least two bits headroom */ | ||
145 | ALLOC( frame_scaled, frame_length, opus_int16 ); | ||
146 | if( shift > 0 ) { | ||
147 | shift = silk_RSHIFT( shift + 1, 1 ); | ||
148 | for( i = 0; i < frame_length; i++ ) { | ||
149 | frame_scaled[ i ] = silk_RSHIFT( frame_unscaled[ i ], shift ); | ||
150 | } | ||
151 | frame = frame_scaled; | ||
152 | } else { | ||
153 | frame = frame_unscaled; | ||
154 | } | ||
155 | |||
156 | ALLOC( frame_8kHz_buf, ( Fs_kHz == 8 ) ? 1 : frame_length_8kHz, opus_int16 ); | ||
157 | /* Resample from input sampled at Fs_kHz to 8 kHz */ | ||
158 | if( Fs_kHz == 16 ) { | ||
159 | silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) ); | ||
160 | silk_resampler_down2( filt_state, frame_8kHz_buf, frame, frame_length ); | ||
161 | frame_8kHz = frame_8kHz_buf; | ||
162 | } else if( Fs_kHz == 12 ) { | ||
163 | silk_memset( filt_state, 0, 6 * sizeof( opus_int32 ) ); | ||
164 | silk_resampler_down2_3( filt_state, frame_8kHz_buf, frame, frame_length ); | ||
165 | frame_8kHz = frame_8kHz_buf; | ||
166 | } else { | ||
167 | celt_assert( Fs_kHz == 8 ); | ||
168 | frame_8kHz = frame; | ||
169 | } | ||
170 | |||
171 | /* Decimate again to 4 kHz */ | ||
172 | silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) );/* Set state to zero */ | ||
173 | ALLOC( frame_4kHz, frame_length_4kHz, opus_int16 ); | ||
174 | silk_resampler_down2( filt_state, frame_4kHz, frame_8kHz, frame_length_8kHz ); | ||
175 | |||
176 | /* Low-pass filter */ | ||
177 | for( i = frame_length_4kHz - 1; i > 0; i-- ) { | ||
178 | frame_4kHz[ i ] = silk_ADD_SAT16( frame_4kHz[ i ], frame_4kHz[ i - 1 ] ); | ||
179 | } | ||
180 | |||
181 | |||
182 | /****************************************************************************** | ||
183 | * FIRST STAGE, operating in 4 khz | ||
184 | ******************************************************************************/ | ||
185 | ALLOC( C, nb_subfr * CSTRIDE_8KHZ, opus_int16 ); | ||
186 | ALLOC( xcorr32, MAX_LAG_4KHZ-MIN_LAG_4KHZ+1, opus_int32 ); | ||
187 | silk_memset( C, 0, (nb_subfr >> 1) * CSTRIDE_4KHZ * sizeof( opus_int16 ) ); | ||
188 | target_ptr = &frame_4kHz[ silk_LSHIFT( SF_LENGTH_4KHZ, 2 ) ]; | ||
189 | for( k = 0; k < nb_subfr >> 1; k++ ) { | ||
190 | /* Check that we are within range of the array */ | ||
191 | celt_assert( target_ptr >= frame_4kHz ); | ||
192 | celt_assert( target_ptr + SF_LENGTH_8KHZ <= frame_4kHz + frame_length_4kHz ); | ||
193 | |||
194 | basis_ptr = target_ptr - MIN_LAG_4KHZ; | ||
195 | |||
196 | /* Check that we are within range of the array */ | ||
197 | celt_assert( basis_ptr >= frame_4kHz ); | ||
198 | celt_assert( basis_ptr + SF_LENGTH_8KHZ <= frame_4kHz + frame_length_4kHz ); | ||
199 | |||
200 | celt_pitch_xcorr( target_ptr, target_ptr - MAX_LAG_4KHZ, xcorr32, SF_LENGTH_8KHZ, MAX_LAG_4KHZ - MIN_LAG_4KHZ + 1, arch ); | ||
201 | |||
202 | /* Calculate first vector products before loop */ | ||
203 | cross_corr = xcorr32[ MAX_LAG_4KHZ - MIN_LAG_4KHZ ]; | ||
204 | normalizer = silk_inner_prod_aligned( target_ptr, target_ptr, SF_LENGTH_8KHZ, arch ); | ||
205 | normalizer = silk_ADD32( normalizer, silk_inner_prod_aligned( basis_ptr, basis_ptr, SF_LENGTH_8KHZ, arch ) ); | ||
206 | normalizer = silk_ADD32( normalizer, silk_SMULBB( SF_LENGTH_8KHZ, 4000 ) ); | ||
207 | |||
208 | matrix_ptr( C, k, 0, CSTRIDE_4KHZ ) = | ||
209 | (opus_int16)silk_DIV32_varQ( cross_corr, normalizer, 13 + 1 ); /* Q13 */ | ||
210 | |||
211 | /* From now on normalizer is computed recursively */ | ||
212 | for( d = MIN_LAG_4KHZ + 1; d <= MAX_LAG_4KHZ; d++ ) { | ||
213 | basis_ptr--; | ||
214 | |||
215 | /* Check that we are within range of the array */ | ||
216 | silk_assert( basis_ptr >= frame_4kHz ); | ||
217 | silk_assert( basis_ptr + SF_LENGTH_8KHZ <= frame_4kHz + frame_length_4kHz ); | ||
218 | |||
219 | cross_corr = xcorr32[ MAX_LAG_4KHZ - d ]; | ||
220 | |||
221 | /* Add contribution of new sample and remove contribution from oldest sample */ | ||
222 | normalizer = silk_ADD32( normalizer, | ||
223 | silk_SMULBB( basis_ptr[ 0 ], basis_ptr[ 0 ] ) - | ||
224 | silk_SMULBB( basis_ptr[ SF_LENGTH_8KHZ ], basis_ptr[ SF_LENGTH_8KHZ ] ) ); | ||
225 | |||
226 | matrix_ptr( C, k, d - MIN_LAG_4KHZ, CSTRIDE_4KHZ) = | ||
227 | (opus_int16)silk_DIV32_varQ( cross_corr, normalizer, 13 + 1 ); /* Q13 */ | ||
228 | } | ||
229 | /* Update target pointer */ | ||
230 | target_ptr += SF_LENGTH_8KHZ; | ||
231 | } | ||
232 | |||
233 | /* Combine two subframes into single correlation measure and apply short-lag bias */ | ||
234 | if( nb_subfr == PE_MAX_NB_SUBFR ) { | ||
235 | for( i = MAX_LAG_4KHZ; i >= MIN_LAG_4KHZ; i-- ) { | ||
236 | sum = (opus_int32)matrix_ptr( C, 0, i - MIN_LAG_4KHZ, CSTRIDE_4KHZ ) | ||
237 | + (opus_int32)matrix_ptr( C, 1, i - MIN_LAG_4KHZ, CSTRIDE_4KHZ ); /* Q14 */ | ||
238 | sum = silk_SMLAWB( sum, sum, silk_LSHIFT( -i, 4 ) ); /* Q14 */ | ||
239 | C[ i - MIN_LAG_4KHZ ] = (opus_int16)sum; /* Q14 */ | ||
240 | } | ||
241 | } else { | ||
242 | /* Only short-lag bias */ | ||
243 | for( i = MAX_LAG_4KHZ; i >= MIN_LAG_4KHZ; i-- ) { | ||
244 | sum = silk_LSHIFT( (opus_int32)C[ i - MIN_LAG_4KHZ ], 1 ); /* Q14 */ | ||
245 | sum = silk_SMLAWB( sum, sum, silk_LSHIFT( -i, 4 ) ); /* Q14 */ | ||
246 | C[ i - MIN_LAG_4KHZ ] = (opus_int16)sum; /* Q14 */ | ||
247 | } | ||
248 | } | ||
249 | |||
250 | /* Sort */ | ||
251 | length_d_srch = silk_ADD_LSHIFT32( 4, complexity, 1 ); | ||
252 | celt_assert( 3 * length_d_srch <= PE_D_SRCH_LENGTH ); | ||
253 | silk_insertion_sort_decreasing_int16( C, d_srch, CSTRIDE_4KHZ, | ||
254 | length_d_srch ); | ||
255 | |||
256 | /* Escape if correlation is very low already here */ | ||
257 | Cmax = (opus_int)C[ 0 ]; /* Q14 */ | ||
258 | if( Cmax < SILK_FIX_CONST( 0.2, 14 ) ) { | ||
259 | silk_memset( pitch_out, 0, nb_subfr * sizeof( opus_int ) ); | ||
260 | *LTPCorr_Q15 = 0; | ||
261 | *lagIndex = 0; | ||
262 | *contourIndex = 0; | ||
263 | RESTORE_STACK; | ||
264 | return 1; | ||
265 | } | ||
266 | |||
267 | threshold = silk_SMULWB( search_thres1_Q16, Cmax ); | ||
268 | for( i = 0; i < length_d_srch; i++ ) { | ||
269 | /* Convert to 8 kHz indices for the sorted correlation that exceeds the threshold */ | ||
270 | if( C[ i ] > threshold ) { | ||
271 | d_srch[ i ] = silk_LSHIFT( d_srch[ i ] + MIN_LAG_4KHZ, 1 ); | ||
272 | } else { | ||
273 | length_d_srch = i; | ||
274 | break; | ||
275 | } | ||
276 | } | ||
277 | celt_assert( length_d_srch > 0 ); | ||
278 | |||
279 | ALLOC( d_comp, D_COMP_STRIDE, opus_int16 ); | ||
280 | for( i = D_COMP_MIN; i < D_COMP_MAX; i++ ) { | ||
281 | d_comp[ i - D_COMP_MIN ] = 0; | ||
282 | } | ||
283 | for( i = 0; i < length_d_srch; i++ ) { | ||
284 | d_comp[ d_srch[ i ] - D_COMP_MIN ] = 1; | ||
285 | } | ||
286 | |||
287 | /* Convolution */ | ||
288 | for( i = D_COMP_MAX - 1; i >= MIN_LAG_8KHZ; i-- ) { | ||
289 | d_comp[ i - D_COMP_MIN ] += | ||
290 | d_comp[ i - 1 - D_COMP_MIN ] + d_comp[ i - 2 - D_COMP_MIN ]; | ||
291 | } | ||
292 | |||
293 | length_d_srch = 0; | ||
294 | for( i = MIN_LAG_8KHZ; i < MAX_LAG_8KHZ + 1; i++ ) { | ||
295 | if( d_comp[ i + 1 - D_COMP_MIN ] > 0 ) { | ||
296 | d_srch[ length_d_srch ] = i; | ||
297 | length_d_srch++; | ||
298 | } | ||
299 | } | ||
300 | |||
301 | /* Convolution */ | ||
302 | for( i = D_COMP_MAX - 1; i >= MIN_LAG_8KHZ; i-- ) { | ||
303 | d_comp[ i - D_COMP_MIN ] += d_comp[ i - 1 - D_COMP_MIN ] | ||
304 | + d_comp[ i - 2 - D_COMP_MIN ] + d_comp[ i - 3 - D_COMP_MIN ]; | ||
305 | } | ||
306 | |||
307 | length_d_comp = 0; | ||
308 | for( i = MIN_LAG_8KHZ; i < D_COMP_MAX; i++ ) { | ||
309 | if( d_comp[ i - D_COMP_MIN ] > 0 ) { | ||
310 | d_comp[ length_d_comp ] = i - 2; | ||
311 | length_d_comp++; | ||
312 | } | ||
313 | } | ||
314 | |||
315 | /********************************************************************************** | ||
316 | ** SECOND STAGE, operating at 8 kHz, on lag sections with high correlation | ||
317 | *************************************************************************************/ | ||
318 | |||
319 | /********************************************************************************* | ||
320 | * Find energy of each subframe projected onto its history, for a range of delays | ||
321 | *********************************************************************************/ | ||
322 | silk_memset( C, 0, nb_subfr * CSTRIDE_8KHZ * sizeof( opus_int16 ) ); | ||
323 | |||
324 | target_ptr = &frame_8kHz[ PE_LTP_MEM_LENGTH_MS * 8 ]; | ||
325 | for( k = 0; k < nb_subfr; k++ ) { | ||
326 | |||
327 | /* Check that we are within range of the array */ | ||
328 | celt_assert( target_ptr >= frame_8kHz ); | ||
329 | celt_assert( target_ptr + SF_LENGTH_8KHZ <= frame_8kHz + frame_length_8kHz ); | ||
330 | |||
331 | energy_target = silk_ADD32( silk_inner_prod_aligned( target_ptr, target_ptr, SF_LENGTH_8KHZ, arch ), 1 ); | ||
332 | for( j = 0; j < length_d_comp; j++ ) { | ||
333 | d = d_comp[ j ]; | ||
334 | basis_ptr = target_ptr - d; | ||
335 | |||
336 | /* Check that we are within range of the array */ | ||
337 | silk_assert( basis_ptr >= frame_8kHz ); | ||
338 | silk_assert( basis_ptr + SF_LENGTH_8KHZ <= frame_8kHz + frame_length_8kHz ); | ||
339 | |||
340 | cross_corr = silk_inner_prod_aligned( target_ptr, basis_ptr, SF_LENGTH_8KHZ, arch ); | ||
341 | if( cross_corr > 0 ) { | ||
342 | energy_basis = silk_inner_prod_aligned( basis_ptr, basis_ptr, SF_LENGTH_8KHZ, arch ); | ||
343 | matrix_ptr( C, k, d - ( MIN_LAG_8KHZ - 2 ), CSTRIDE_8KHZ ) = | ||
344 | (opus_int16)silk_DIV32_varQ( cross_corr, | ||
345 | silk_ADD32( energy_target, | ||
346 | energy_basis ), | ||
347 | 13 + 1 ); /* Q13 */ | ||
348 | } else { | ||
349 | matrix_ptr( C, k, d - ( MIN_LAG_8KHZ - 2 ), CSTRIDE_8KHZ ) = 0; | ||
350 | } | ||
351 | } | ||
352 | target_ptr += SF_LENGTH_8KHZ; | ||
353 | } | ||
354 | |||
355 | /* search over lag range and lags codebook */ | ||
356 | /* scale factor for lag codebook, as a function of center lag */ | ||
357 | |||
358 | CCmax = silk_int32_MIN; | ||
359 | CCmax_b = silk_int32_MIN; | ||
360 | |||
361 | CBimax = 0; /* To avoid returning undefined lag values */ | ||
362 | lag = -1; /* To check if lag with strong enough correlation has been found */ | ||
363 | |||
364 | if( prevLag > 0 ) { | ||
365 | if( Fs_kHz == 12 ) { | ||
366 | prevLag = silk_DIV32_16( silk_LSHIFT( prevLag, 1 ), 3 ); | ||
367 | } else if( Fs_kHz == 16 ) { | ||
368 | prevLag = silk_RSHIFT( prevLag, 1 ); | ||
369 | } | ||
370 | prevLag_log2_Q7 = silk_lin2log( (opus_int32)prevLag ); | ||
371 | } else { | ||
372 | prevLag_log2_Q7 = 0; | ||
373 | } | ||
374 | silk_assert( search_thres2_Q13 == silk_SAT16( search_thres2_Q13 ) ); | ||
375 | /* Set up stage 2 codebook based on number of subframes */ | ||
376 | if( nb_subfr == PE_MAX_NB_SUBFR ) { | ||
377 | cbk_size = PE_NB_CBKS_STAGE2_EXT; | ||
378 | Lag_CB_ptr = &silk_CB_lags_stage2[ 0 ][ 0 ]; | ||
379 | if( Fs_kHz == 8 && complexity > SILK_PE_MIN_COMPLEX ) { | ||
380 | /* If input is 8 khz use a larger codebook here because it is last stage */ | ||
381 | nb_cbk_search = PE_NB_CBKS_STAGE2_EXT; | ||
382 | } else { | ||
383 | nb_cbk_search = PE_NB_CBKS_STAGE2; | ||
384 | } | ||
385 | } else { | ||
386 | cbk_size = PE_NB_CBKS_STAGE2_10MS; | ||
387 | Lag_CB_ptr = &silk_CB_lags_stage2_10_ms[ 0 ][ 0 ]; | ||
388 | nb_cbk_search = PE_NB_CBKS_STAGE2_10MS; | ||
389 | } | ||
390 | |||
391 | for( k = 0; k < length_d_srch; k++ ) { | ||
392 | d = d_srch[ k ]; | ||
393 | for( j = 0; j < nb_cbk_search; j++ ) { | ||
394 | CC[ j ] = 0; | ||
395 | for( i = 0; i < nb_subfr; i++ ) { | ||
396 | opus_int d_subfr; | ||
397 | /* Try all codebooks */ | ||
398 | d_subfr = d + matrix_ptr( Lag_CB_ptr, i, j, cbk_size ); | ||
399 | CC[ j ] = CC[ j ] | ||
400 | + (opus_int32)matrix_ptr( C, i, | ||
401 | d_subfr - ( MIN_LAG_8KHZ - 2 ), | ||
402 | CSTRIDE_8KHZ ); | ||
403 | } | ||
404 | } | ||
405 | /* Find best codebook */ | ||
406 | CCmax_new = silk_int32_MIN; | ||
407 | CBimax_new = 0; | ||
408 | for( i = 0; i < nb_cbk_search; i++ ) { | ||
409 | if( CC[ i ] > CCmax_new ) { | ||
410 | CCmax_new = CC[ i ]; | ||
411 | CBimax_new = i; | ||
412 | } | ||
413 | } | ||
414 | |||
415 | /* Bias towards shorter lags */ | ||
416 | lag_log2_Q7 = silk_lin2log( d ); /* Q7 */ | ||
417 | silk_assert( lag_log2_Q7 == silk_SAT16( lag_log2_Q7 ) ); | ||
418 | silk_assert( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 13 ) == silk_SAT16( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 13 ) ) ); | ||
419 | CCmax_new_b = CCmax_new - silk_RSHIFT( silk_SMULBB( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 13 ), lag_log2_Q7 ), 7 ); /* Q13 */ | ||
420 | |||
421 | /* Bias towards previous lag */ | ||
422 | silk_assert( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 13 ) == silk_SAT16( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 13 ) ) ); | ||
423 | if( prevLag > 0 ) { | ||
424 | delta_lag_log2_sqr_Q7 = lag_log2_Q7 - prevLag_log2_Q7; | ||
425 | silk_assert( delta_lag_log2_sqr_Q7 == silk_SAT16( delta_lag_log2_sqr_Q7 ) ); | ||
426 | delta_lag_log2_sqr_Q7 = silk_RSHIFT( silk_SMULBB( delta_lag_log2_sqr_Q7, delta_lag_log2_sqr_Q7 ), 7 ); | ||
427 | prev_lag_bias_Q13 = silk_RSHIFT( silk_SMULBB( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 13 ), *LTPCorr_Q15 ), 15 ); /* Q13 */ | ||
428 | prev_lag_bias_Q13 = silk_DIV32( silk_MUL( prev_lag_bias_Q13, delta_lag_log2_sqr_Q7 ), delta_lag_log2_sqr_Q7 + SILK_FIX_CONST( 0.5, 7 ) ); | ||
429 | CCmax_new_b -= prev_lag_bias_Q13; /* Q13 */ | ||
430 | } | ||
431 | |||
432 | if( CCmax_new_b > CCmax_b && /* Find maximum biased correlation */ | ||
433 | CCmax_new > silk_SMULBB( nb_subfr, search_thres2_Q13 ) && /* Correlation needs to be high enough to be voiced */ | ||
434 | silk_CB_lags_stage2[ 0 ][ CBimax_new ] <= MIN_LAG_8KHZ /* Lag must be in range */ | ||
435 | ) { | ||
436 | CCmax_b = CCmax_new_b; | ||
437 | CCmax = CCmax_new; | ||
438 | lag = d; | ||
439 | CBimax = CBimax_new; | ||
440 | } | ||
441 | } | ||
442 | |||
443 | if( lag == -1 ) { | ||
444 | /* No suitable candidate found */ | ||
445 | silk_memset( pitch_out, 0, nb_subfr * sizeof( opus_int ) ); | ||
446 | *LTPCorr_Q15 = 0; | ||
447 | *lagIndex = 0; | ||
448 | *contourIndex = 0; | ||
449 | RESTORE_STACK; | ||
450 | return 1; | ||
451 | } | ||
452 | |||
453 | /* Output normalized correlation */ | ||
454 | *LTPCorr_Q15 = (opus_int)silk_LSHIFT( silk_DIV32_16( CCmax, nb_subfr ), 2 ); | ||
455 | silk_assert( *LTPCorr_Q15 >= 0 ); | ||
456 | |||
457 | if( Fs_kHz > 8 ) { | ||
458 | /* Search in original signal */ | ||
459 | |||
460 | CBimax_old = CBimax; | ||
461 | /* Compensate for decimation */ | ||
462 | silk_assert( lag == silk_SAT16( lag ) ); | ||
463 | if( Fs_kHz == 12 ) { | ||
464 | lag = silk_RSHIFT( silk_SMULBB( lag, 3 ), 1 ); | ||
465 | } else if( Fs_kHz == 16 ) { | ||
466 | lag = silk_LSHIFT( lag, 1 ); | ||
467 | } else { | ||
468 | lag = silk_SMULBB( lag, 3 ); | ||
469 | } | ||
470 | |||
471 | lag = silk_LIMIT_int( lag, min_lag, max_lag ); | ||
472 | start_lag = silk_max_int( lag - 2, min_lag ); | ||
473 | end_lag = silk_min_int( lag + 2, max_lag ); | ||
474 | lag_new = lag; /* to avoid undefined lag */ | ||
475 | CBimax = 0; /* to avoid undefined lag */ | ||
476 | |||
477 | CCmax = silk_int32_MIN; | ||
478 | /* pitch lags according to second stage */ | ||
479 | for( k = 0; k < nb_subfr; k++ ) { | ||
480 | pitch_out[ k ] = lag + 2 * silk_CB_lags_stage2[ k ][ CBimax_old ]; | ||
481 | } | ||
482 | |||
483 | /* Set up codebook parameters according to complexity setting and frame length */ | ||
484 | if( nb_subfr == PE_MAX_NB_SUBFR ) { | ||
485 | nb_cbk_search = (opus_int)silk_nb_cbk_searchs_stage3[ complexity ]; | ||
486 | cbk_size = PE_NB_CBKS_STAGE3_MAX; | ||
487 | Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ]; | ||
488 | } else { | ||
489 | nb_cbk_search = PE_NB_CBKS_STAGE3_10MS; | ||
490 | cbk_size = PE_NB_CBKS_STAGE3_10MS; | ||
491 | Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ]; | ||
492 | } | ||
493 | |||
494 | /* Calculate the correlations and energies needed in stage 3 */ | ||
495 | ALLOC( energies_st3, nb_subfr * nb_cbk_search, silk_pe_stage3_vals ); | ||
496 | ALLOC( cross_corr_st3, nb_subfr * nb_cbk_search, silk_pe_stage3_vals ); | ||
497 | silk_P_Ana_calc_corr_st3( cross_corr_st3, frame, start_lag, sf_length, nb_subfr, complexity, arch ); | ||
498 | silk_P_Ana_calc_energy_st3( energies_st3, frame, start_lag, sf_length, nb_subfr, complexity, arch ); | ||
499 | |||
500 | lag_counter = 0; | ||
501 | silk_assert( lag == silk_SAT16( lag ) ); | ||
502 | contour_bias_Q15 = silk_DIV32_16( SILK_FIX_CONST( PE_FLATCONTOUR_BIAS, 15 ), lag ); | ||
503 | |||
504 | target_ptr = &frame[ PE_LTP_MEM_LENGTH_MS * Fs_kHz ]; | ||
505 | energy_target = silk_ADD32( silk_inner_prod_aligned( target_ptr, target_ptr, nb_subfr * sf_length, arch ), 1 ); | ||
506 | for( d = start_lag; d <= end_lag; d++ ) { | ||
507 | for( j = 0; j < nb_cbk_search; j++ ) { | ||
508 | cross_corr = 0; | ||
509 | energy = energy_target; | ||
510 | for( k = 0; k < nb_subfr; k++ ) { | ||
511 | cross_corr = silk_ADD32( cross_corr, | ||
512 | matrix_ptr( cross_corr_st3, k, j, | ||
513 | nb_cbk_search )[ lag_counter ] ); | ||
514 | energy = silk_ADD32( energy, | ||
515 | matrix_ptr( energies_st3, k, j, | ||
516 | nb_cbk_search )[ lag_counter ] ); | ||
517 | silk_assert( energy >= 0 ); | ||
518 | } | ||
519 | if( cross_corr > 0 ) { | ||
520 | CCmax_new = silk_DIV32_varQ( cross_corr, energy, 13 + 1 ); /* Q13 */ | ||
521 | /* Reduce depending on flatness of contour */ | ||
522 | diff = silk_int16_MAX - silk_MUL( contour_bias_Q15, j ); /* Q15 */ | ||
523 | silk_assert( diff == silk_SAT16( diff ) ); | ||
524 | CCmax_new = silk_SMULWB( CCmax_new, diff ); /* Q14 */ | ||
525 | } else { | ||
526 | CCmax_new = 0; | ||
527 | } | ||
528 | |||
529 | if( CCmax_new > CCmax && ( d + silk_CB_lags_stage3[ 0 ][ j ] ) <= max_lag ) { | ||
530 | CCmax = CCmax_new; | ||
531 | lag_new = d; | ||
532 | CBimax = j; | ||
533 | } | ||
534 | } | ||
535 | lag_counter++; | ||
536 | } | ||
537 | |||
538 | for( k = 0; k < nb_subfr; k++ ) { | ||
539 | pitch_out[ k ] = lag_new + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size ); | ||
540 | pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], min_lag, PE_MAX_LAG_MS * Fs_kHz ); | ||
541 | } | ||
542 | *lagIndex = (opus_int16)( lag_new - min_lag); | ||
543 | *contourIndex = (opus_int8)CBimax; | ||
544 | } else { /* Fs_kHz == 8 */ | ||
545 | /* Save Lags */ | ||
546 | for( k = 0; k < nb_subfr; k++ ) { | ||
547 | pitch_out[ k ] = lag + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size ); | ||
548 | pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], MIN_LAG_8KHZ, PE_MAX_LAG_MS * 8 ); | ||
549 | } | ||
550 | *lagIndex = (opus_int16)( lag - MIN_LAG_8KHZ ); | ||
551 | *contourIndex = (opus_int8)CBimax; | ||
552 | } | ||
553 | celt_assert( *lagIndex >= 0 ); | ||
554 | /* return as voiced */ | ||
555 | RESTORE_STACK; | ||
556 | return 0; | ||
557 | } | ||
558 | |||
559 | /*********************************************************************** | ||
560 | * Calculates the correlations used in stage 3 search. In order to cover | ||
561 | * the whole lag codebook for all the searched offset lags (lag +- 2), | ||
562 | * the following correlations are needed in each sub frame: | ||
563 | * | ||
564 | * sf1: lag range [-8,...,7] total 16 correlations | ||
565 | * sf2: lag range [-4,...,4] total 9 correlations | ||
566 | * sf3: lag range [-3,....4] total 8 correltions | ||
567 | * sf4: lag range [-6,....8] total 15 correlations | ||
568 | * | ||
569 | * In total 48 correlations. The direct implementation computed in worst | ||
570 | * case 4*12*5 = 240 correlations, but more likely around 120. | ||
571 | ***********************************************************************/ | ||
572 | static void silk_P_Ana_calc_corr_st3( | ||
573 | silk_pe_stage3_vals cross_corr_st3[], /* O 3 DIM correlation array */ | ||
574 | const opus_int16 frame[], /* I vector to correlate */ | ||
575 | opus_int start_lag, /* I lag offset to search around */ | ||
576 | opus_int sf_length, /* I length of a 5 ms subframe */ | ||
577 | opus_int nb_subfr, /* I number of subframes */ | ||
578 | opus_int complexity, /* I Complexity setting */ | ||
579 | int arch /* I Run-time architecture */ | ||
580 | ) | ||
581 | { | ||
582 | const opus_int16 *target_ptr; | ||
583 | opus_int i, j, k, lag_counter, lag_low, lag_high; | ||
584 | opus_int nb_cbk_search, delta, idx, cbk_size; | ||
585 | VARDECL( opus_int32, scratch_mem ); | ||
586 | VARDECL( opus_int32, xcorr32 ); | ||
587 | const opus_int8 *Lag_range_ptr, *Lag_CB_ptr; | ||
588 | SAVE_STACK; | ||
589 | |||
590 | celt_assert( complexity >= SILK_PE_MIN_COMPLEX ); | ||
591 | celt_assert( complexity <= SILK_PE_MAX_COMPLEX ); | ||
592 | |||
593 | if( nb_subfr == PE_MAX_NB_SUBFR ) { | ||
594 | Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ]; | ||
595 | Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ]; | ||
596 | nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ]; | ||
597 | cbk_size = PE_NB_CBKS_STAGE3_MAX; | ||
598 | } else { | ||
599 | celt_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1); | ||
600 | Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ]; | ||
601 | Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ]; | ||
602 | nb_cbk_search = PE_NB_CBKS_STAGE3_10MS; | ||
603 | cbk_size = PE_NB_CBKS_STAGE3_10MS; | ||
604 | } | ||
605 | ALLOC( scratch_mem, SCRATCH_SIZE, opus_int32 ); | ||
606 | ALLOC( xcorr32, SCRATCH_SIZE, opus_int32 ); | ||
607 | |||
608 | target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ]; /* Pointer to middle of frame */ | ||
609 | for( k = 0; k < nb_subfr; k++ ) { | ||
610 | lag_counter = 0; | ||
611 | |||
612 | /* Calculate the correlations for each subframe */ | ||
613 | lag_low = matrix_ptr( Lag_range_ptr, k, 0, 2 ); | ||
614 | lag_high = matrix_ptr( Lag_range_ptr, k, 1, 2 ); | ||
615 | celt_assert(lag_high-lag_low+1 <= SCRATCH_SIZE); | ||
616 | celt_pitch_xcorr( target_ptr, target_ptr - start_lag - lag_high, xcorr32, sf_length, lag_high - lag_low + 1, arch ); | ||
617 | for( j = lag_low; j <= lag_high; j++ ) { | ||
618 | silk_assert( lag_counter < SCRATCH_SIZE ); | ||
619 | scratch_mem[ lag_counter ] = xcorr32[ lag_high - j ]; | ||
620 | lag_counter++; | ||
621 | } | ||
622 | |||
623 | delta = matrix_ptr( Lag_range_ptr, k, 0, 2 ); | ||
624 | for( i = 0; i < nb_cbk_search; i++ ) { | ||
625 | /* Fill out the 3 dim array that stores the correlations for */ | ||
626 | /* each code_book vector for each start lag */ | ||
627 | idx = matrix_ptr( Lag_CB_ptr, k, i, cbk_size ) - delta; | ||
628 | for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) { | ||
629 | silk_assert( idx + j < SCRATCH_SIZE ); | ||
630 | silk_assert( idx + j < lag_counter ); | ||
631 | matrix_ptr( cross_corr_st3, k, i, nb_cbk_search )[ j ] = | ||
632 | scratch_mem[ idx + j ]; | ||
633 | } | ||
634 | } | ||
635 | target_ptr += sf_length; | ||
636 | } | ||
637 | RESTORE_STACK; | ||
638 | } | ||
639 | |||
640 | /********************************************************************/ | ||
641 | /* Calculate the energies for first two subframes. The energies are */ | ||
642 | /* calculated recursively. */ | ||
643 | /********************************************************************/ | ||
644 | static void silk_P_Ana_calc_energy_st3( | ||
645 | silk_pe_stage3_vals energies_st3[], /* O 3 DIM energy array */ | ||
646 | const opus_int16 frame[], /* I vector to calc energy in */ | ||
647 | opus_int start_lag, /* I lag offset to search around */ | ||
648 | opus_int sf_length, /* I length of one 5 ms subframe */ | ||
649 | opus_int nb_subfr, /* I number of subframes */ | ||
650 | opus_int complexity, /* I Complexity setting */ | ||
651 | int arch /* I Run-time architecture */ | ||
652 | ) | ||
653 | { | ||
654 | const opus_int16 *target_ptr, *basis_ptr; | ||
655 | opus_int32 energy; | ||
656 | opus_int k, i, j, lag_counter; | ||
657 | opus_int nb_cbk_search, delta, idx, cbk_size, lag_diff; | ||
658 | VARDECL( opus_int32, scratch_mem ); | ||
659 | const opus_int8 *Lag_range_ptr, *Lag_CB_ptr; | ||
660 | SAVE_STACK; | ||
661 | |||
662 | celt_assert( complexity >= SILK_PE_MIN_COMPLEX ); | ||
663 | celt_assert( complexity <= SILK_PE_MAX_COMPLEX ); | ||
664 | |||
665 | if( nb_subfr == PE_MAX_NB_SUBFR ) { | ||
666 | Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ]; | ||
667 | Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ]; | ||
668 | nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ]; | ||
669 | cbk_size = PE_NB_CBKS_STAGE3_MAX; | ||
670 | } else { | ||
671 | celt_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1); | ||
672 | Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ]; | ||
673 | Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ]; | ||
674 | nb_cbk_search = PE_NB_CBKS_STAGE3_10MS; | ||
675 | cbk_size = PE_NB_CBKS_STAGE3_10MS; | ||
676 | } | ||
677 | ALLOC( scratch_mem, SCRATCH_SIZE, opus_int32 ); | ||
678 | |||
679 | target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ]; | ||
680 | for( k = 0; k < nb_subfr; k++ ) { | ||
681 | lag_counter = 0; | ||
682 | |||
683 | /* Calculate the energy for first lag */ | ||
684 | basis_ptr = target_ptr - ( start_lag + matrix_ptr( Lag_range_ptr, k, 0, 2 ) ); | ||
685 | energy = silk_inner_prod_aligned( basis_ptr, basis_ptr, sf_length, arch ); | ||
686 | silk_assert( energy >= 0 ); | ||
687 | scratch_mem[ lag_counter ] = energy; | ||
688 | lag_counter++; | ||
689 | |||
690 | lag_diff = ( matrix_ptr( Lag_range_ptr, k, 1, 2 ) - matrix_ptr( Lag_range_ptr, k, 0, 2 ) + 1 ); | ||
691 | for( i = 1; i < lag_diff; i++ ) { | ||
692 | /* remove part outside new window */ | ||
693 | energy -= silk_SMULBB( basis_ptr[ sf_length - i ], basis_ptr[ sf_length - i ] ); | ||
694 | silk_assert( energy >= 0 ); | ||
695 | |||
696 | /* add part that comes into window */ | ||
697 | energy = silk_ADD_SAT32( energy, silk_SMULBB( basis_ptr[ -i ], basis_ptr[ -i ] ) ); | ||
698 | silk_assert( energy >= 0 ); | ||
699 | silk_assert( lag_counter < SCRATCH_SIZE ); | ||
700 | scratch_mem[ lag_counter ] = energy; | ||
701 | lag_counter++; | ||
702 | } | ||
703 | |||
704 | delta = matrix_ptr( Lag_range_ptr, k, 0, 2 ); | ||
705 | for( i = 0; i < nb_cbk_search; i++ ) { | ||
706 | /* Fill out the 3 dim array that stores the correlations for */ | ||
707 | /* each code_book vector for each start lag */ | ||
708 | idx = matrix_ptr( Lag_CB_ptr, k, i, cbk_size ) - delta; | ||
709 | for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) { | ||
710 | silk_assert( idx + j < SCRATCH_SIZE ); | ||
711 | silk_assert( idx + j < lag_counter ); | ||
712 | matrix_ptr( energies_st3, k, i, nb_cbk_search )[ j ] = | ||
713 | scratch_mem[ idx + j ]; | ||
714 | silk_assert( | ||
715 | matrix_ptr( energies_st3, k, i, nb_cbk_search )[ j ] >= 0 ); | ||
716 | } | ||
717 | } | ||
718 | target_ptr += sf_length; | ||
719 | } | ||
720 | RESTORE_STACK; | ||
721 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/process_gains_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/process_gains_FIX.c new file mode 100644 index 0000000000..05aba31788 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/fixed/process_gains_FIX.c | |||
@@ -0,0 +1,117 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main_FIX.h" | ||
33 | #include "tuning_parameters.h" | ||
34 | |||
35 | /* Processing of gains */ | ||
36 | void silk_process_gains_FIX( | ||
37 | silk_encoder_state_FIX *psEnc, /* I/O Encoder state */ | ||
38 | silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control */ | ||
39 | opus_int condCoding /* I The type of conditional coding to use */ | ||
40 | ) | ||
41 | { | ||
42 | silk_shape_state_FIX *psShapeSt = &psEnc->sShape; | ||
43 | opus_int k; | ||
44 | opus_int32 s_Q16, InvMaxSqrVal_Q16, gain, gain_squared, ResNrg, ResNrgPart, quant_offset_Q10; | ||
45 | |||
46 | /* Gain reduction when LTP coding gain is high */ | ||
47 | if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { | ||
48 | /*s = -0.5f * silk_sigmoid( 0.25f * ( psEncCtrl->LTPredCodGain - 12.0f ) ); */ | ||
49 | s_Q16 = -silk_sigm_Q15( silk_RSHIFT_ROUND( psEncCtrl->LTPredCodGain_Q7 - SILK_FIX_CONST( 12.0, 7 ), 4 ) ); | ||
50 | for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { | ||
51 | psEncCtrl->Gains_Q16[ k ] = silk_SMLAWB( psEncCtrl->Gains_Q16[ k ], psEncCtrl->Gains_Q16[ k ], s_Q16 ); | ||
52 | } | ||
53 | } | ||
54 | |||
55 | /* Limit the quantized signal */ | ||
56 | /* InvMaxSqrVal = pow( 2.0f, 0.33f * ( 21.0f - SNR_dB ) ) / subfr_length; */ | ||
57 | InvMaxSqrVal_Q16 = silk_DIV32_16( silk_log2lin( | ||
58 | silk_SMULWB( SILK_FIX_CONST( 21 + 16 / 0.33, 7 ) - psEnc->sCmn.SNR_dB_Q7, SILK_FIX_CONST( 0.33, 16 ) ) ), psEnc->sCmn.subfr_length ); | ||
59 | |||
60 | for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { | ||
61 | /* Soft limit on ratio residual energy and squared gains */ | ||
62 | ResNrg = psEncCtrl->ResNrg[ k ]; | ||
63 | ResNrgPart = silk_SMULWW( ResNrg, InvMaxSqrVal_Q16 ); | ||
64 | if( psEncCtrl->ResNrgQ[ k ] > 0 ) { | ||
65 | ResNrgPart = silk_RSHIFT_ROUND( ResNrgPart, psEncCtrl->ResNrgQ[ k ] ); | ||
66 | } else { | ||
67 | if( ResNrgPart >= silk_RSHIFT( silk_int32_MAX, -psEncCtrl->ResNrgQ[ k ] ) ) { | ||
68 | ResNrgPart = silk_int32_MAX; | ||
69 | } else { | ||
70 | ResNrgPart = silk_LSHIFT( ResNrgPart, -psEncCtrl->ResNrgQ[ k ] ); | ||
71 | } | ||
72 | } | ||
73 | gain = psEncCtrl->Gains_Q16[ k ]; | ||
74 | gain_squared = silk_ADD_SAT32( ResNrgPart, silk_SMMUL( gain, gain ) ); | ||
75 | if( gain_squared < silk_int16_MAX ) { | ||
76 | /* recalculate with higher precision */ | ||
77 | gain_squared = silk_SMLAWW( silk_LSHIFT( ResNrgPart, 16 ), gain, gain ); | ||
78 | silk_assert( gain_squared > 0 ); | ||
79 | gain = silk_SQRT_APPROX( gain_squared ); /* Q8 */ | ||
80 | gain = silk_min( gain, silk_int32_MAX >> 8 ); | ||
81 | psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT_SAT32( gain, 8 ); /* Q16 */ | ||
82 | } else { | ||
83 | gain = silk_SQRT_APPROX( gain_squared ); /* Q0 */ | ||
84 | gain = silk_min( gain, silk_int32_MAX >> 16 ); | ||
85 | psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT_SAT32( gain, 16 ); /* Q16 */ | ||
86 | } | ||
87 | } | ||
88 | |||
89 | /* Save unquantized gains and gain Index */ | ||
90 | silk_memcpy( psEncCtrl->GainsUnq_Q16, psEncCtrl->Gains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) ); | ||
91 | psEncCtrl->lastGainIndexPrev = psShapeSt->LastGainIndex; | ||
92 | |||
93 | /* Quantize gains */ | ||
94 | silk_gains_quant( psEnc->sCmn.indices.GainsIndices, psEncCtrl->Gains_Q16, | ||
95 | &psShapeSt->LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr ); | ||
96 | |||
97 | /* Set quantizer offset for voiced signals. Larger offset when LTP coding gain is low or tilt is high (ie low-pass) */ | ||
98 | if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { | ||
99 | if( psEncCtrl->LTPredCodGain_Q7 + silk_RSHIFT( psEnc->sCmn.input_tilt_Q15, 8 ) > SILK_FIX_CONST( 1.0, 7 ) ) { | ||
100 | psEnc->sCmn.indices.quantOffsetType = 0; | ||
101 | } else { | ||
102 | psEnc->sCmn.indices.quantOffsetType = 1; | ||
103 | } | ||
104 | } | ||
105 | |||
106 | /* Quantizer boundary adjustment */ | ||
107 | quant_offset_Q10 = silk_Quantization_Offsets_Q10[ psEnc->sCmn.indices.signalType >> 1 ][ psEnc->sCmn.indices.quantOffsetType ]; | ||
108 | psEncCtrl->Lambda_Q10 = SILK_FIX_CONST( LAMBDA_OFFSET, 10 ) | ||
109 | + silk_SMULBB( SILK_FIX_CONST( LAMBDA_DELAYED_DECISIONS, 10 ), psEnc->sCmn.nStatesDelayedDecision ) | ||
110 | + silk_SMULWB( SILK_FIX_CONST( LAMBDA_SPEECH_ACT, 18 ), psEnc->sCmn.speech_activity_Q8 ) | ||
111 | + silk_SMULWB( SILK_FIX_CONST( LAMBDA_INPUT_QUALITY, 12 ), psEncCtrl->input_quality_Q14 ) | ||
112 | + silk_SMULWB( SILK_FIX_CONST( LAMBDA_CODING_QUALITY, 12 ), psEncCtrl->coding_quality_Q14 ) | ||
113 | + silk_SMULWB( SILK_FIX_CONST( LAMBDA_QUANT_OFFSET, 16 ), quant_offset_Q10 ); | ||
114 | |||
115 | silk_assert( psEncCtrl->Lambda_Q10 > 0 ); | ||
116 | silk_assert( psEncCtrl->Lambda_Q10 < SILK_FIX_CONST( 2, 10 ) ); | ||
117 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/regularize_correlations_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/regularize_correlations_FIX.c new file mode 100644 index 0000000000..a2836b05f4 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/fixed/regularize_correlations_FIX.c | |||
@@ -0,0 +1,47 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main_FIX.h" | ||
33 | |||
34 | /* Add noise to matrix diagonal */ | ||
35 | void silk_regularize_correlations_FIX( | ||
36 | opus_int32 *XX, /* I/O Correlation matrices */ | ||
37 | opus_int32 *xx, /* I/O Correlation values */ | ||
38 | opus_int32 noise, /* I Noise to add */ | ||
39 | opus_int D /* I Dimension of XX */ | ||
40 | ) | ||
41 | { | ||
42 | opus_int i; | ||
43 | for( i = 0; i < D; i++ ) { | ||
44 | matrix_ptr( &XX[ 0 ], i, i, D ) = silk_ADD32( matrix_ptr( &XX[ 0 ], i, i, D ), noise ); | ||
45 | } | ||
46 | xx[ 0 ] += noise; | ||
47 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/residual_energy16_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/residual_energy16_FIX.c new file mode 100644 index 0000000000..7f130f3d3d --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/fixed/residual_energy16_FIX.c | |||
@@ -0,0 +1,103 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main_FIX.h" | ||
33 | |||
34 | /* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */ | ||
35 | opus_int32 silk_residual_energy16_covar_FIX( | ||
36 | const opus_int16 *c, /* I Prediction vector */ | ||
37 | const opus_int32 *wXX, /* I Correlation matrix */ | ||
38 | const opus_int32 *wXx, /* I Correlation vector */ | ||
39 | opus_int32 wxx, /* I Signal energy */ | ||
40 | opus_int D, /* I Dimension */ | ||
41 | opus_int cQ /* I Q value for c vector 0 - 15 */ | ||
42 | ) | ||
43 | { | ||
44 | opus_int i, j, lshifts, Qxtra; | ||
45 | opus_int32 c_max, w_max, tmp, tmp2, nrg; | ||
46 | opus_int cn[ MAX_MATRIX_SIZE ]; | ||
47 | const opus_int32 *pRow; | ||
48 | |||
49 | /* Safety checks */ | ||
50 | celt_assert( D >= 0 ); | ||
51 | celt_assert( D <= 16 ); | ||
52 | celt_assert( cQ > 0 ); | ||
53 | celt_assert( cQ < 16 ); | ||
54 | |||
55 | lshifts = 16 - cQ; | ||
56 | Qxtra = lshifts; | ||
57 | |||
58 | c_max = 0; | ||
59 | for( i = 0; i < D; i++ ) { | ||
60 | c_max = silk_max_32( c_max, silk_abs( (opus_int32)c[ i ] ) ); | ||
61 | } | ||
62 | Qxtra = silk_min_int( Qxtra, silk_CLZ32( c_max ) - 17 ); | ||
63 | |||
64 | w_max = silk_max_32( wXX[ 0 ], wXX[ D * D - 1 ] ); | ||
65 | Qxtra = silk_min_int( Qxtra, silk_CLZ32( silk_MUL( D, silk_RSHIFT( silk_SMULWB( w_max, c_max ), 4 ) ) ) - 5 ); | ||
66 | Qxtra = silk_max_int( Qxtra, 0 ); | ||
67 | for( i = 0; i < D; i++ ) { | ||
68 | cn[ i ] = silk_LSHIFT( ( opus_int )c[ i ], Qxtra ); | ||
69 | silk_assert( silk_abs(cn[i]) <= ( silk_int16_MAX + 1 ) ); /* Check that silk_SMLAWB can be used */ | ||
70 | } | ||
71 | lshifts -= Qxtra; | ||
72 | |||
73 | /* Compute wxx - 2 * wXx * c */ | ||
74 | tmp = 0; | ||
75 | for( i = 0; i < D; i++ ) { | ||
76 | tmp = silk_SMLAWB( tmp, wXx[ i ], cn[ i ] ); | ||
77 | } | ||
78 | nrg = silk_RSHIFT( wxx, 1 + lshifts ) - tmp; /* Q: -lshifts - 1 */ | ||
79 | |||
80 | /* Add c' * wXX * c, assuming wXX is symmetric */ | ||
81 | tmp2 = 0; | ||
82 | for( i = 0; i < D; i++ ) { | ||
83 | tmp = 0; | ||
84 | pRow = &wXX[ i * D ]; | ||
85 | for( j = i + 1; j < D; j++ ) { | ||
86 | tmp = silk_SMLAWB( tmp, pRow[ j ], cn[ j ] ); | ||
87 | } | ||
88 | tmp = silk_SMLAWB( tmp, silk_RSHIFT( pRow[ i ], 1 ), cn[ i ] ); | ||
89 | tmp2 = silk_SMLAWB( tmp2, tmp, cn[ i ] ); | ||
90 | } | ||
91 | nrg = silk_ADD_LSHIFT32( nrg, tmp2, lshifts ); /* Q: -lshifts - 1 */ | ||
92 | |||
93 | /* Keep one bit free always, because we add them for LSF interpolation */ | ||
94 | if( nrg < 1 ) { | ||
95 | nrg = 1; | ||
96 | } else if( nrg > silk_RSHIFT( silk_int32_MAX, lshifts + 2 ) ) { | ||
97 | nrg = silk_int32_MAX >> 1; | ||
98 | } else { | ||
99 | nrg = silk_LSHIFT( nrg, lshifts + 1 ); /* Q0 */ | ||
100 | } | ||
101 | return nrg; | ||
102 | |||
103 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/residual_energy_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/residual_energy_FIX.c new file mode 100644 index 0000000000..6c7cade9a0 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/fixed/residual_energy_FIX.c | |||
@@ -0,0 +1,98 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main_FIX.h" | ||
33 | #include "stack_alloc.h" | ||
34 | |||
35 | /* Calculates residual energies of input subframes where all subframes have LPC_order */ | ||
36 | /* of preceding samples */ | ||
37 | void silk_residual_energy_FIX( | ||
38 | opus_int32 nrgs[ MAX_NB_SUBFR ], /* O Residual energy per subframe */ | ||
39 | opus_int nrgsQ[ MAX_NB_SUBFR ], /* O Q value per subframe */ | ||
40 | const opus_int16 x[], /* I Input signal */ | ||
41 | opus_int16 a_Q12[ 2 ][ MAX_LPC_ORDER ], /* I AR coefs for each frame half */ | ||
42 | const opus_int32 gains[ MAX_NB_SUBFR ], /* I Quantization gains */ | ||
43 | const opus_int subfr_length, /* I Subframe length */ | ||
44 | const opus_int nb_subfr, /* I Number of subframes */ | ||
45 | const opus_int LPC_order, /* I LPC order */ | ||
46 | int arch /* I Run-time architecture */ | ||
47 | ) | ||
48 | { | ||
49 | opus_int offset, i, j, rshift, lz1, lz2; | ||
50 | opus_int16 *LPC_res_ptr; | ||
51 | VARDECL( opus_int16, LPC_res ); | ||
52 | const opus_int16 *x_ptr; | ||
53 | opus_int32 tmp32; | ||
54 | SAVE_STACK; | ||
55 | |||
56 | x_ptr = x; | ||
57 | offset = LPC_order + subfr_length; | ||
58 | |||
59 | /* Filter input to create the LPC residual for each frame half, and measure subframe energies */ | ||
60 | ALLOC( LPC_res, ( MAX_NB_SUBFR >> 1 ) * offset, opus_int16 ); | ||
61 | celt_assert( ( nb_subfr >> 1 ) * ( MAX_NB_SUBFR >> 1 ) == nb_subfr ); | ||
62 | for( i = 0; i < nb_subfr >> 1; i++ ) { | ||
63 | /* Calculate half frame LPC residual signal including preceding samples */ | ||
64 | silk_LPC_analysis_filter( LPC_res, x_ptr, a_Q12[ i ], ( MAX_NB_SUBFR >> 1 ) * offset, LPC_order, arch ); | ||
65 | |||
66 | /* Point to first subframe of the just calculated LPC residual signal */ | ||
67 | LPC_res_ptr = LPC_res + LPC_order; | ||
68 | for( j = 0; j < ( MAX_NB_SUBFR >> 1 ); j++ ) { | ||
69 | /* Measure subframe energy */ | ||
70 | silk_sum_sqr_shift( &nrgs[ i * ( MAX_NB_SUBFR >> 1 ) + j ], &rshift, LPC_res_ptr, subfr_length ); | ||
71 | |||
72 | /* Set Q values for the measured energy */ | ||
73 | nrgsQ[ i * ( MAX_NB_SUBFR >> 1 ) + j ] = -rshift; | ||
74 | |||
75 | /* Move to next subframe */ | ||
76 | LPC_res_ptr += offset; | ||
77 | } | ||
78 | /* Move to next frame half */ | ||
79 | x_ptr += ( MAX_NB_SUBFR >> 1 ) * offset; | ||
80 | } | ||
81 | |||
82 | /* Apply the squared subframe gains */ | ||
83 | for( i = 0; i < nb_subfr; i++ ) { | ||
84 | /* Fully upscale gains and energies */ | ||
85 | lz1 = silk_CLZ32( nrgs[ i ] ) - 1; | ||
86 | lz2 = silk_CLZ32( gains[ i ] ) - 1; | ||
87 | |||
88 | tmp32 = silk_LSHIFT32( gains[ i ], lz2 ); | ||
89 | |||
90 | /* Find squared gains */ | ||
91 | tmp32 = silk_SMMUL( tmp32, tmp32 ); /* Q( 2 * lz2 - 32 )*/ | ||
92 | |||
93 | /* Scale energies */ | ||
94 | nrgs[ i ] = silk_SMMUL( tmp32, silk_LSHIFT32( nrgs[ i ], lz1 ) ); /* Q( nrgsQ[ i ] + lz1 + 2 * lz2 - 32 - 32 )*/ | ||
95 | nrgsQ[ i ] += lz1 + 2 * lz2 - 32 - 32; | ||
96 | } | ||
97 | RESTORE_STACK; | ||
98 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/schur64_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/schur64_FIX.c new file mode 100644 index 0000000000..4b7e19ea59 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/fixed/schur64_FIX.c | |||
@@ -0,0 +1,93 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "SigProc_FIX.h" | ||
33 | |||
34 | /* Slower than schur(), but more accurate. */ | ||
35 | /* Uses SMULL(), available on armv4 */ | ||
36 | opus_int32 silk_schur64( /* O returns residual energy */ | ||
37 | opus_int32 rc_Q16[], /* O Reflection coefficients [order] Q16 */ | ||
38 | const opus_int32 c[], /* I Correlations [order+1] */ | ||
39 | opus_int32 order /* I Prediction order */ | ||
40 | ) | ||
41 | { | ||
42 | opus_int k, n; | ||
43 | opus_int32 C[ SILK_MAX_ORDER_LPC + 1 ][ 2 ]; | ||
44 | opus_int32 Ctmp1_Q30, Ctmp2_Q30, rc_tmp_Q31; | ||
45 | |||
46 | celt_assert( order >= 0 && order <= SILK_MAX_ORDER_LPC ); | ||
47 | |||
48 | /* Check for invalid input */ | ||
49 | if( c[ 0 ] <= 0 ) { | ||
50 | silk_memset( rc_Q16, 0, order * sizeof( opus_int32 ) ); | ||
51 | return 0; | ||
52 | } | ||
53 | |||
54 | k = 0; | ||
55 | do { | ||
56 | C[ k ][ 0 ] = C[ k ][ 1 ] = c[ k ]; | ||
57 | } while( ++k <= order ); | ||
58 | |||
59 | for( k = 0; k < order; k++ ) { | ||
60 | /* Check that we won't be getting an unstable rc, otherwise stop here. */ | ||
61 | if (silk_abs_int32(C[ k + 1 ][ 0 ]) >= C[ 0 ][ 1 ]) { | ||
62 | if ( C[ k + 1 ][ 0 ] > 0 ) { | ||
63 | rc_Q16[ k ] = -SILK_FIX_CONST( .99f, 16 ); | ||
64 | } else { | ||
65 | rc_Q16[ k ] = SILK_FIX_CONST( .99f, 16 ); | ||
66 | } | ||
67 | k++; | ||
68 | break; | ||
69 | } | ||
70 | |||
71 | /* Get reflection coefficient: divide two Q30 values and get result in Q31 */ | ||
72 | rc_tmp_Q31 = silk_DIV32_varQ( -C[ k + 1 ][ 0 ], C[ 0 ][ 1 ], 31 ); | ||
73 | |||
74 | /* Save the output */ | ||
75 | rc_Q16[ k ] = silk_RSHIFT_ROUND( rc_tmp_Q31, 15 ); | ||
76 | |||
77 | /* Update correlations */ | ||
78 | for( n = 0; n < order - k; n++ ) { | ||
79 | Ctmp1_Q30 = C[ n + k + 1 ][ 0 ]; | ||
80 | Ctmp2_Q30 = C[ n ][ 1 ]; | ||
81 | |||
82 | /* Multiply and add the highest int32 */ | ||
83 | C[ n + k + 1 ][ 0 ] = Ctmp1_Q30 + silk_SMMUL( silk_LSHIFT( Ctmp2_Q30, 1 ), rc_tmp_Q31 ); | ||
84 | C[ n ][ 1 ] = Ctmp2_Q30 + silk_SMMUL( silk_LSHIFT( Ctmp1_Q30, 1 ), rc_tmp_Q31 ); | ||
85 | } | ||
86 | } | ||
87 | |||
88 | for(; k < order; k++ ) { | ||
89 | rc_Q16[ k ] = 0; | ||
90 | } | ||
91 | |||
92 | return silk_max_32( 1, C[ 0 ][ 1 ] ); | ||
93 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/schur_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/schur_FIX.c new file mode 100644 index 0000000000..2840f6b1aa --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/fixed/schur_FIX.c | |||
@@ -0,0 +1,107 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "SigProc_FIX.h" | ||
33 | |||
34 | /* Faster than schur64(), but much less accurate. */ | ||
35 | /* uses SMLAWB(), requiring armv5E and higher. */ | ||
36 | opus_int32 silk_schur( /* O Returns residual energy */ | ||
37 | opus_int16 *rc_Q15, /* O reflection coefficients [order] Q15 */ | ||
38 | const opus_int32 *c, /* I correlations [order+1] */ | ||
39 | const opus_int32 order /* I prediction order */ | ||
40 | ) | ||
41 | { | ||
42 | opus_int k, n, lz; | ||
43 | opus_int32 C[ SILK_MAX_ORDER_LPC + 1 ][ 2 ]; | ||
44 | opus_int32 Ctmp1, Ctmp2, rc_tmp_Q15; | ||
45 | |||
46 | celt_assert( order >= 0 && order <= SILK_MAX_ORDER_LPC ); | ||
47 | |||
48 | /* Get number of leading zeros */ | ||
49 | lz = silk_CLZ32( c[ 0 ] ); | ||
50 | |||
51 | /* Copy correlations and adjust level to Q30 */ | ||
52 | k = 0; | ||
53 | if( lz < 2 ) { | ||
54 | /* lz must be 1, so shift one to the right */ | ||
55 | do { | ||
56 | C[ k ][ 0 ] = C[ k ][ 1 ] = silk_RSHIFT( c[ k ], 1 ); | ||
57 | } while( ++k <= order ); | ||
58 | } else if( lz > 2 ) { | ||
59 | /* Shift to the left */ | ||
60 | lz -= 2; | ||
61 | do { | ||
62 | C[ k ][ 0 ] = C[ k ][ 1 ] = silk_LSHIFT( c[ k ], lz ); | ||
63 | } while( ++k <= order ); | ||
64 | } else { | ||
65 | /* No need to shift */ | ||
66 | do { | ||
67 | C[ k ][ 0 ] = C[ k ][ 1 ] = c[ k ]; | ||
68 | } while( ++k <= order ); | ||
69 | } | ||
70 | |||
71 | for( k = 0; k < order; k++ ) { | ||
72 | /* Check that we won't be getting an unstable rc, otherwise stop here. */ | ||
73 | if (silk_abs_int32(C[ k + 1 ][ 0 ]) >= C[ 0 ][ 1 ]) { | ||
74 | if ( C[ k + 1 ][ 0 ] > 0 ) { | ||
75 | rc_Q15[ k ] = -SILK_FIX_CONST( .99f, 15 ); | ||
76 | } else { | ||
77 | rc_Q15[ k ] = SILK_FIX_CONST( .99f, 15 ); | ||
78 | } | ||
79 | k++; | ||
80 | break; | ||
81 | } | ||
82 | |||
83 | /* Get reflection coefficient */ | ||
84 | rc_tmp_Q15 = -silk_DIV32_16( C[ k + 1 ][ 0 ], silk_max_32( silk_RSHIFT( C[ 0 ][ 1 ], 15 ), 1 ) ); | ||
85 | |||
86 | /* Clip (shouldn't happen for properly conditioned inputs) */ | ||
87 | rc_tmp_Q15 = silk_SAT16( rc_tmp_Q15 ); | ||
88 | |||
89 | /* Store */ | ||
90 | rc_Q15[ k ] = (opus_int16)rc_tmp_Q15; | ||
91 | |||
92 | /* Update correlations */ | ||
93 | for( n = 0; n < order - k; n++ ) { | ||
94 | Ctmp1 = C[ n + k + 1 ][ 0 ]; | ||
95 | Ctmp2 = C[ n ][ 1 ]; | ||
96 | C[ n + k + 1 ][ 0 ] = silk_SMLAWB( Ctmp1, silk_LSHIFT( Ctmp2, 1 ), rc_tmp_Q15 ); | ||
97 | C[ n ][ 1 ] = silk_SMLAWB( Ctmp2, silk_LSHIFT( Ctmp1, 1 ), rc_tmp_Q15 ); | ||
98 | } | ||
99 | } | ||
100 | |||
101 | for(; k < order; k++ ) { | ||
102 | rc_Q15[ k ] = 0; | ||
103 | } | ||
104 | |||
105 | /* return residual energy */ | ||
106 | return silk_max_32( 1, C[ 0 ][ 1 ] ); | ||
107 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/structs_FIX.h b/lib/rbcodec/codecs/libopus/silk/fixed/structs_FIX.h new file mode 100644 index 0000000000..2774a97b24 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/fixed/structs_FIX.h | |||
@@ -0,0 +1,116 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifndef SILK_STRUCTS_FIX_H | ||
29 | #define SILK_STRUCTS_FIX_H | ||
30 | |||
31 | #include "typedef.h" | ||
32 | #include "main.h" | ||
33 | #include "structs.h" | ||
34 | |||
35 | #ifdef __cplusplus | ||
36 | extern "C" | ||
37 | { | ||
38 | #endif | ||
39 | |||
40 | /********************************/ | ||
41 | /* Noise shaping analysis state */ | ||
42 | /********************************/ | ||
43 | typedef struct { | ||
44 | opus_int8 LastGainIndex; | ||
45 | opus_int32 HarmBoost_smth_Q16; | ||
46 | opus_int32 HarmShapeGain_smth_Q16; | ||
47 | opus_int32 Tilt_smth_Q16; | ||
48 | } silk_shape_state_FIX; | ||
49 | |||
50 | /********************************/ | ||
51 | /* Encoder state FIX */ | ||
52 | /********************************/ | ||
53 | typedef struct { | ||
54 | silk_encoder_state sCmn; /* Common struct, shared with floating-point code */ | ||
55 | silk_shape_state_FIX sShape; /* Shape state */ | ||
56 | |||
57 | /* Buffer for find pitch and noise shape analysis */ | ||
58 | silk_DWORD_ALIGN opus_int16 x_buf[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ];/* Buffer for find pitch and noise shape analysis */ | ||
59 | opus_int LTPCorr_Q15; /* Normalized correlation from pitch lag estimator */ | ||
60 | opus_int32 resNrgSmth; | ||
61 | } silk_encoder_state_FIX; | ||
62 | |||
63 | /************************/ | ||
64 | /* Encoder control FIX */ | ||
65 | /************************/ | ||
66 | typedef struct { | ||
67 | /* Prediction and coding parameters */ | ||
68 | opus_int32 Gains_Q16[ MAX_NB_SUBFR ]; | ||
69 | silk_DWORD_ALIGN opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ]; | ||
70 | opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ]; | ||
71 | opus_int LTP_scale_Q14; | ||
72 | opus_int pitchL[ MAX_NB_SUBFR ]; | ||
73 | |||
74 | /* Noise shaping parameters */ | ||
75 | /* Testing */ | ||
76 | silk_DWORD_ALIGN opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ]; | ||
77 | opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ]; /* Packs two int16 coefficients per int32 value */ | ||
78 | opus_int Tilt_Q14[ MAX_NB_SUBFR ]; | ||
79 | opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ]; | ||
80 | opus_int Lambda_Q10; | ||
81 | opus_int input_quality_Q14; | ||
82 | opus_int coding_quality_Q14; | ||
83 | |||
84 | /* measures */ | ||
85 | opus_int32 predGain_Q16; | ||
86 | opus_int LTPredCodGain_Q7; | ||
87 | opus_int32 ResNrg[ MAX_NB_SUBFR ]; /* Residual energy per subframe */ | ||
88 | opus_int ResNrgQ[ MAX_NB_SUBFR ]; /* Q domain for the residual energy > 0 */ | ||
89 | |||
90 | /* Parameters for CBR mode */ | ||
91 | opus_int32 GainsUnq_Q16[ MAX_NB_SUBFR ]; | ||
92 | opus_int8 lastGainIndexPrev; | ||
93 | } silk_encoder_control_FIX; | ||
94 | |||
95 | /************************/ | ||
96 | /* Encoder Super Struct */ | ||
97 | /************************/ | ||
98 | typedef struct { | ||
99 | silk_encoder_state_FIX state_Fxx[ ENCODER_NUM_CHANNELS ]; | ||
100 | stereo_enc_state sStereo; | ||
101 | opus_int32 nBitsUsedLBRR; | ||
102 | opus_int32 nBitsExceeded; | ||
103 | opus_int nChannelsAPI; | ||
104 | opus_int nChannelsInternal; | ||
105 | opus_int nPrevChannelsInternal; | ||
106 | opus_int timeSinceSwitchAllowed_ms; | ||
107 | opus_int allowBandwidthSwitch; | ||
108 | opus_int prev_decode_only_middle; | ||
109 | } silk_encoder; | ||
110 | |||
111 | |||
112 | #ifdef __cplusplus | ||
113 | } | ||
114 | #endif | ||
115 | |||
116 | #endif | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/vector_ops_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/vector_ops_FIX.c new file mode 100644 index 0000000000..d94980014f --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/fixed/vector_ops_FIX.c | |||
@@ -0,0 +1,102 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "SigProc_FIX.h" | ||
33 | #include "pitch.h" | ||
34 | |||
35 | /* Copy and multiply a vector by a constant */ | ||
36 | void silk_scale_copy_vector16( | ||
37 | opus_int16 *data_out, | ||
38 | const opus_int16 *data_in, | ||
39 | opus_int32 gain_Q16, /* I Gain in Q16 */ | ||
40 | const opus_int dataSize /* I Length */ | ||
41 | ) | ||
42 | { | ||
43 | opus_int i; | ||
44 | opus_int32 tmp32; | ||
45 | |||
46 | for( i = 0; i < dataSize; i++ ) { | ||
47 | tmp32 = silk_SMULWB( gain_Q16, data_in[ i ] ); | ||
48 | data_out[ i ] = (opus_int16)silk_CHECK_FIT16( tmp32 ); | ||
49 | } | ||
50 | } | ||
51 | |||
52 | /* Multiply a vector by a constant */ | ||
53 | void silk_scale_vector32_Q26_lshift_18( | ||
54 | opus_int32 *data1, /* I/O Q0/Q18 */ | ||
55 | opus_int32 gain_Q26, /* I Q26 */ | ||
56 | opus_int dataSize /* I length */ | ||
57 | ) | ||
58 | { | ||
59 | opus_int i; | ||
60 | |||
61 | for( i = 0; i < dataSize; i++ ) { | ||
62 | data1[ i ] = (opus_int32)silk_CHECK_FIT32( silk_RSHIFT64( silk_SMULL( data1[ i ], gain_Q26 ), 8 ) ); /* OUTPUT: Q18 */ | ||
63 | } | ||
64 | } | ||
65 | |||
66 | /* sum = for(i=0;i<len;i++)inVec1[i]*inVec2[i]; --- inner product */ | ||
67 | /* Note for ARM asm: */ | ||
68 | /* * inVec1 and inVec2 should be at least 2 byte aligned. */ | ||
69 | /* * len should be positive 16bit integer. */ | ||
70 | /* * only when len>6, memory access can be reduced by half. */ | ||
71 | opus_int32 silk_inner_prod_aligned( | ||
72 | const opus_int16 *const inVec1, /* I input vector 1 */ | ||
73 | const opus_int16 *const inVec2, /* I input vector 2 */ | ||
74 | const opus_int len, /* I vector lengths */ | ||
75 | int arch /* I Run-time architecture */ | ||
76 | ) | ||
77 | { | ||
78 | #ifdef FIXED_POINT | ||
79 | return celt_inner_prod(inVec1, inVec2, len, arch); | ||
80 | #else | ||
81 | opus_int i; | ||
82 | opus_int32 sum = 0; | ||
83 | for( i = 0; i < len; i++ ) { | ||
84 | sum = silk_SMLABB( sum, inVec1[ i ], inVec2[ i ] ); | ||
85 | } | ||
86 | return sum; | ||
87 | #endif | ||
88 | } | ||
89 | |||
90 | opus_int64 silk_inner_prod16_aligned_64_c( | ||
91 | const opus_int16 *inVec1, /* I input vector 1 */ | ||
92 | const opus_int16 *inVec2, /* I input vector 2 */ | ||
93 | const opus_int len /* I vector lengths */ | ||
94 | ) | ||
95 | { | ||
96 | opus_int i; | ||
97 | opus_int64 sum = 0; | ||
98 | for( i = 0; i < len; i++ ) { | ||
99 | sum = silk_SMLALBB( sum, inVec1[ i ], inVec2[ i ] ); | ||
100 | } | ||
101 | return sum; | ||
102 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/warped_autocorrelation_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/warped_autocorrelation_FIX.c new file mode 100644 index 0000000000..52002a1118 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/fixed/warped_autocorrelation_FIX.c | |||
@@ -0,0 +1,90 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main_FIX.h" | ||
33 | |||
34 | #if defined(MIPSr1_ASM) | ||
35 | #include "mips/warped_autocorrelation_FIX_mipsr1.h" | ||
36 | #endif | ||
37 | |||
38 | |||
39 | /* Autocorrelations for a warped frequency axis */ | ||
40 | void silk_warped_autocorrelation_FIX_c( | ||
41 | opus_int32 *corr, /* O Result [order + 1] */ | ||
42 | opus_int *scale, /* O Scaling of the correlation vector */ | ||
43 | const opus_int16 *input, /* I Input data to correlate */ | ||
44 | const opus_int warping_Q16, /* I Warping coefficient */ | ||
45 | const opus_int length, /* I Length of input */ | ||
46 | const opus_int order /* I Correlation order (even) */ | ||
47 | ) | ||
48 | { | ||
49 | opus_int n, i, lsh; | ||
50 | opus_int32 tmp1_QS, tmp2_QS; | ||
51 | opus_int32 state_QS[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 }; | ||
52 | opus_int64 corr_QC[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 }; | ||
53 | |||
54 | /* Order must be even */ | ||
55 | celt_assert( ( order & 1 ) == 0 ); | ||
56 | silk_assert( 2 * QS - QC >= 0 ); | ||
57 | |||
58 | /* Loop over samples */ | ||
59 | for( n = 0; n < length; n++ ) { | ||
60 | tmp1_QS = silk_LSHIFT32( (opus_int32)input[ n ], QS ); | ||
61 | /* Loop over allpass sections */ | ||
62 | for( i = 0; i < order; i += 2 ) { | ||
63 | /* Output of allpass section */ | ||
64 | tmp2_QS = silk_SMLAWB( state_QS[ i ], state_QS[ i + 1 ] - tmp1_QS, warping_Q16 ); | ||
65 | state_QS[ i ] = tmp1_QS; | ||
66 | corr_QC[ i ] += silk_RSHIFT64( silk_SMULL( tmp1_QS, state_QS[ 0 ] ), 2 * QS - QC ); | ||
67 | /* Output of allpass section */ | ||
68 | tmp1_QS = silk_SMLAWB( state_QS[ i + 1 ], state_QS[ i + 2 ] - tmp2_QS, warping_Q16 ); | ||
69 | state_QS[ i + 1 ] = tmp2_QS; | ||
70 | corr_QC[ i + 1 ] += silk_RSHIFT64( silk_SMULL( tmp2_QS, state_QS[ 0 ] ), 2 * QS - QC ); | ||
71 | } | ||
72 | state_QS[ order ] = tmp1_QS; | ||
73 | corr_QC[ order ] += silk_RSHIFT64( silk_SMULL( tmp1_QS, state_QS[ 0 ] ), 2 * QS - QC ); | ||
74 | } | ||
75 | |||
76 | lsh = silk_CLZ64( corr_QC[ 0 ] ) - 35; | ||
77 | lsh = silk_LIMIT( lsh, -12 - QC, 30 - QC ); | ||
78 | *scale = -( QC + lsh ); | ||
79 | silk_assert( *scale >= -30 && *scale <= 12 ); | ||
80 | if( lsh >= 0 ) { | ||
81 | for( i = 0; i < order + 1; i++ ) { | ||
82 | corr[ i ] = (opus_int32)silk_CHECK_FIT32( silk_LSHIFT64( corr_QC[ i ], lsh ) ); | ||
83 | } | ||
84 | } else { | ||
85 | for( i = 0; i < order + 1; i++ ) { | ||
86 | corr[ i ] = (opus_int32)silk_CHECK_FIT32( silk_RSHIFT64( corr_QC[ i ], -lsh ) ); | ||
87 | } | ||
88 | } | ||
89 | silk_assert( corr_QC[ 0 ] >= 0 ); /* If breaking, decrease QC*/ | ||
90 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/x86/burg_modified_FIX_sse4_1.c b/lib/rbcodec/codecs/libopus/silk/fixed/x86/burg_modified_FIX_sse4_1.c new file mode 100644 index 0000000000..bbb1ce0fcc --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/fixed/x86/burg_modified_FIX_sse4_1.c | |||
@@ -0,0 +1,377 @@ | |||
1 | /* Copyright (c) 2014, Cisco Systems, INC | ||
2 | Written by XiangMingZhu WeiZhou MinPeng YanWang | ||
3 | |||
4 | Redistribution and use in source and binary forms, with or without | ||
5 | modification, are permitted provided that the following conditions | ||
6 | are met: | ||
7 | |||
8 | - Redistributions of source code must retain the above copyright | ||
9 | notice, this list of conditions and the following disclaimer. | ||
10 | |||
11 | - Redistributions in binary form must reproduce the above copyright | ||
12 | notice, this list of conditions and the following disclaimer in the | ||
13 | documentation and/or other materials provided with the distribution. | ||
14 | |||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
16 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
17 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
18 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER | ||
19 | OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
20 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
21 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
22 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
23 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
24 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include <xmmintrin.h> | ||
33 | #include <emmintrin.h> | ||
34 | #include <smmintrin.h> | ||
35 | |||
36 | #include "SigProc_FIX.h" | ||
37 | #include "define.h" | ||
38 | #include "tuning_parameters.h" | ||
39 | #include "pitch.h" | ||
40 | #include "celt/x86/x86cpu.h" | ||
41 | |||
42 | #define MAX_FRAME_SIZE 384 /* subfr_length * nb_subfr = ( 0.005 * 16000 + 16 ) * 4 = 384 */ | ||
43 | |||
44 | #define QA 25 | ||
45 | #define N_BITS_HEAD_ROOM 2 | ||
46 | #define MIN_RSHIFTS -16 | ||
47 | #define MAX_RSHIFTS (32 - QA) | ||
48 | |||
49 | /* Compute reflection coefficients from input signal */ | ||
50 | void silk_burg_modified_sse4_1( | ||
51 | opus_int32 *res_nrg, /* O Residual energy */ | ||
52 | opus_int *res_nrg_Q, /* O Residual energy Q value */ | ||
53 | opus_int32 A_Q16[], /* O Prediction coefficients (length order) */ | ||
54 | const opus_int16 x[], /* I Input signal, length: nb_subfr * ( D + subfr_length ) */ | ||
55 | const opus_int32 minInvGain_Q30, /* I Inverse of max prediction gain */ | ||
56 | const opus_int subfr_length, /* I Input signal subframe length (incl. D preceding samples) */ | ||
57 | const opus_int nb_subfr, /* I Number of subframes stacked in x */ | ||
58 | const opus_int D, /* I Order */ | ||
59 | int arch /* I Run-time architecture */ | ||
60 | ) | ||
61 | { | ||
62 | opus_int k, n, s, lz, rshifts, rshifts_extra, reached_max_gain; | ||
63 | opus_int32 C0, num, nrg, rc_Q31, invGain_Q30, Atmp_QA, Atmp1, tmp1, tmp2, x1, x2; | ||
64 | const opus_int16 *x_ptr; | ||
65 | opus_int32 C_first_row[ SILK_MAX_ORDER_LPC ]; | ||
66 | opus_int32 C_last_row[ SILK_MAX_ORDER_LPC ]; | ||
67 | opus_int32 Af_QA[ SILK_MAX_ORDER_LPC ]; | ||
68 | opus_int32 CAf[ SILK_MAX_ORDER_LPC + 1 ]; | ||
69 | opus_int32 CAb[ SILK_MAX_ORDER_LPC + 1 ]; | ||
70 | opus_int32 xcorr[ SILK_MAX_ORDER_LPC ]; | ||
71 | |||
72 | __m128i FIRST_3210, LAST_3210, ATMP_3210, TMP1_3210, TMP2_3210, T1_3210, T2_3210, PTR_3210, SUBFR_3210, X1_3210, X2_3210; | ||
73 | __m128i CONST1 = _mm_set1_epi32(1); | ||
74 | |||
75 | celt_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE ); | ||
76 | |||
77 | /* Compute autocorrelations, added over subframes */ | ||
78 | silk_sum_sqr_shift( &C0, &rshifts, x, nb_subfr * subfr_length ); | ||
79 | if( rshifts > MAX_RSHIFTS ) { | ||
80 | C0 = silk_LSHIFT32( C0, rshifts - MAX_RSHIFTS ); | ||
81 | silk_assert( C0 > 0 ); | ||
82 | rshifts = MAX_RSHIFTS; | ||
83 | } else { | ||
84 | lz = silk_CLZ32( C0 ) - 1; | ||
85 | rshifts_extra = N_BITS_HEAD_ROOM - lz; | ||
86 | if( rshifts_extra > 0 ) { | ||
87 | rshifts_extra = silk_min( rshifts_extra, MAX_RSHIFTS - rshifts ); | ||
88 | C0 = silk_RSHIFT32( C0, rshifts_extra ); | ||
89 | } else { | ||
90 | rshifts_extra = silk_max( rshifts_extra, MIN_RSHIFTS - rshifts ); | ||
91 | C0 = silk_LSHIFT32( C0, -rshifts_extra ); | ||
92 | } | ||
93 | rshifts += rshifts_extra; | ||
94 | } | ||
95 | CAb[ 0 ] = CAf[ 0 ] = C0 + silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ) + 1; /* Q(-rshifts) */ | ||
96 | silk_memset( C_first_row, 0, SILK_MAX_ORDER_LPC * sizeof( opus_int32 ) ); | ||
97 | if( rshifts > 0 ) { | ||
98 | for( s = 0; s < nb_subfr; s++ ) { | ||
99 | x_ptr = x + s * subfr_length; | ||
100 | for( n = 1; n < D + 1; n++ ) { | ||
101 | C_first_row[ n - 1 ] += (opus_int32)silk_RSHIFT64( | ||
102 | silk_inner_prod16_aligned_64( x_ptr, x_ptr + n, subfr_length - n, arch ), rshifts ); | ||
103 | } | ||
104 | } | ||
105 | } else { | ||
106 | for( s = 0; s < nb_subfr; s++ ) { | ||
107 | int i; | ||
108 | opus_int32 d; | ||
109 | x_ptr = x + s * subfr_length; | ||
110 | celt_pitch_xcorr(x_ptr, x_ptr + 1, xcorr, subfr_length - D, D, arch ); | ||
111 | for( n = 1; n < D + 1; n++ ) { | ||
112 | for ( i = n + subfr_length - D, d = 0; i < subfr_length; i++ ) | ||
113 | d = MAC16_16( d, x_ptr[ i ], x_ptr[ i - n ] ); | ||
114 | xcorr[ n - 1 ] += d; | ||
115 | } | ||
116 | for( n = 1; n < D + 1; n++ ) { | ||
117 | C_first_row[ n - 1 ] += silk_LSHIFT32( xcorr[ n - 1 ], -rshifts ); | ||
118 | } | ||
119 | } | ||
120 | } | ||
121 | silk_memcpy( C_last_row, C_first_row, SILK_MAX_ORDER_LPC * sizeof( opus_int32 ) ); | ||
122 | |||
123 | /* Initialize */ | ||
124 | CAb[ 0 ] = CAf[ 0 ] = C0 + silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ) + 1; /* Q(-rshifts) */ | ||
125 | |||
126 | invGain_Q30 = (opus_int32)1 << 30; | ||
127 | reached_max_gain = 0; | ||
128 | for( n = 0; n < D; n++ ) { | ||
129 | /* Update first row of correlation matrix (without first element) */ | ||
130 | /* Update last row of correlation matrix (without last element, stored in reversed order) */ | ||
131 | /* Update C * Af */ | ||
132 | /* Update C * flipud(Af) (stored in reversed order) */ | ||
133 | if( rshifts > -2 ) { | ||
134 | for( s = 0; s < nb_subfr; s++ ) { | ||
135 | x_ptr = x + s * subfr_length; | ||
136 | x1 = -silk_LSHIFT32( (opus_int32)x_ptr[ n ], 16 - rshifts ); /* Q(16-rshifts) */ | ||
137 | x2 = -silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], 16 - rshifts ); /* Q(16-rshifts) */ | ||
138 | tmp1 = silk_LSHIFT32( (opus_int32)x_ptr[ n ], QA - 16 ); /* Q(QA-16) */ | ||
139 | tmp2 = silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], QA - 16 ); /* Q(QA-16) */ | ||
140 | for( k = 0; k < n; k++ ) { | ||
141 | C_first_row[ k ] = silk_SMLAWB( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); /* Q( -rshifts ) */ | ||
142 | C_last_row[ k ] = silk_SMLAWB( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts ) */ | ||
143 | Atmp_QA = Af_QA[ k ]; | ||
144 | tmp1 = silk_SMLAWB( tmp1, Atmp_QA, x_ptr[ n - k - 1 ] ); /* Q(QA-16) */ | ||
145 | tmp2 = silk_SMLAWB( tmp2, Atmp_QA, x_ptr[ subfr_length - n + k ] ); /* Q(QA-16) */ | ||
146 | } | ||
147 | tmp1 = silk_LSHIFT32( -tmp1, 32 - QA - rshifts ); /* Q(16-rshifts) */ | ||
148 | tmp2 = silk_LSHIFT32( -tmp2, 32 - QA - rshifts ); /* Q(16-rshifts) */ | ||
149 | for( k = 0; k <= n; k++ ) { | ||
150 | CAf[ k ] = silk_SMLAWB( CAf[ k ], tmp1, x_ptr[ n - k ] ); /* Q( -rshift ) */ | ||
151 | CAb[ k ] = silk_SMLAWB( CAb[ k ], tmp2, x_ptr[ subfr_length - n + k - 1 ] ); /* Q( -rshift ) */ | ||
152 | } | ||
153 | } | ||
154 | } else { | ||
155 | for( s = 0; s < nb_subfr; s++ ) { | ||
156 | x_ptr = x + s * subfr_length; | ||
157 | x1 = -silk_LSHIFT32( (opus_int32)x_ptr[ n ], -rshifts ); /* Q( -rshifts ) */ | ||
158 | x2 = -silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], -rshifts ); /* Q( -rshifts ) */ | ||
159 | tmp1 = silk_LSHIFT32( (opus_int32)x_ptr[ n ], 17 ); /* Q17 */ | ||
160 | tmp2 = silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], 17 ); /* Q17 */ | ||
161 | |||
162 | X1_3210 = _mm_set1_epi32( x1 ); | ||
163 | X2_3210 = _mm_set1_epi32( x2 ); | ||
164 | TMP1_3210 = _mm_setzero_si128(); | ||
165 | TMP2_3210 = _mm_setzero_si128(); | ||
166 | for( k = 0; k < n - 3; k += 4 ) { | ||
167 | PTR_3210 = OP_CVTEPI16_EPI32_M64( &x_ptr[ n - k - 1 - 3 ] ); | ||
168 | SUBFR_3210 = OP_CVTEPI16_EPI32_M64( &x_ptr[ subfr_length - n + k ] ); | ||
169 | FIRST_3210 = _mm_loadu_si128( (__m128i *)&C_first_row[ k ] ); | ||
170 | PTR_3210 = _mm_shuffle_epi32( PTR_3210, _MM_SHUFFLE( 0, 1, 2, 3 ) ); | ||
171 | LAST_3210 = _mm_loadu_si128( (__m128i *)&C_last_row[ k ] ); | ||
172 | ATMP_3210 = _mm_loadu_si128( (__m128i *)&Af_QA[ k ] ); | ||
173 | |||
174 | T1_3210 = _mm_mullo_epi32( PTR_3210, X1_3210 ); | ||
175 | T2_3210 = _mm_mullo_epi32( SUBFR_3210, X2_3210 ); | ||
176 | |||
177 | ATMP_3210 = _mm_srai_epi32( ATMP_3210, 7 ); | ||
178 | ATMP_3210 = _mm_add_epi32( ATMP_3210, CONST1 ); | ||
179 | ATMP_3210 = _mm_srai_epi32( ATMP_3210, 1 ); | ||
180 | |||
181 | FIRST_3210 = _mm_add_epi32( FIRST_3210, T1_3210 ); | ||
182 | LAST_3210 = _mm_add_epi32( LAST_3210, T2_3210 ); | ||
183 | |||
184 | PTR_3210 = _mm_mullo_epi32( ATMP_3210, PTR_3210 ); | ||
185 | SUBFR_3210 = _mm_mullo_epi32( ATMP_3210, SUBFR_3210 ); | ||
186 | |||
187 | _mm_storeu_si128( (__m128i *)&C_first_row[ k ], FIRST_3210 ); | ||
188 | _mm_storeu_si128( (__m128i *)&C_last_row[ k ], LAST_3210 ); | ||
189 | |||
190 | TMP1_3210 = _mm_add_epi32( TMP1_3210, PTR_3210 ); | ||
191 | TMP2_3210 = _mm_add_epi32( TMP2_3210, SUBFR_3210 ); | ||
192 | } | ||
193 | |||
194 | TMP1_3210 = _mm_add_epi32( TMP1_3210, _mm_unpackhi_epi64(TMP1_3210, TMP1_3210 ) ); | ||
195 | TMP2_3210 = _mm_add_epi32( TMP2_3210, _mm_unpackhi_epi64(TMP2_3210, TMP2_3210 ) ); | ||
196 | TMP1_3210 = _mm_add_epi32( TMP1_3210, _mm_shufflelo_epi16(TMP1_3210, 0x0E ) ); | ||
197 | TMP2_3210 = _mm_add_epi32( TMP2_3210, _mm_shufflelo_epi16(TMP2_3210, 0x0E ) ); | ||
198 | |||
199 | tmp1 += _mm_cvtsi128_si32( TMP1_3210 ); | ||
200 | tmp2 += _mm_cvtsi128_si32( TMP2_3210 ); | ||
201 | |||
202 | for( ; k < n; k++ ) { | ||
203 | C_first_row[ k ] = silk_MLA( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); /* Q( -rshifts ) */ | ||
204 | C_last_row[ k ] = silk_MLA( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts ) */ | ||
205 | Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 17 ); /* Q17 */ | ||
206 | tmp1 = silk_MLA( tmp1, x_ptr[ n - k - 1 ], Atmp1 ); /* Q17 */ | ||
207 | tmp2 = silk_MLA( tmp2, x_ptr[ subfr_length - n + k ], Atmp1 ); /* Q17 */ | ||
208 | } | ||
209 | |||
210 | tmp1 = -tmp1; /* Q17 */ | ||
211 | tmp2 = -tmp2; /* Q17 */ | ||
212 | |||
213 | { | ||
214 | __m128i xmm_tmp1, xmm_tmp2; | ||
215 | __m128i xmm_x_ptr_n_k_x2x0, xmm_x_ptr_n_k_x3x1; | ||
216 | __m128i xmm_x_ptr_sub_x2x0, xmm_x_ptr_sub_x3x1; | ||
217 | |||
218 | xmm_tmp1 = _mm_set1_epi32( tmp1 ); | ||
219 | xmm_tmp2 = _mm_set1_epi32( tmp2 ); | ||
220 | |||
221 | for( k = 0; k <= n - 3; k += 4 ) { | ||
222 | xmm_x_ptr_n_k_x2x0 = OP_CVTEPI16_EPI32_M64( &x_ptr[ n - k - 3 ] ); | ||
223 | xmm_x_ptr_sub_x2x0 = OP_CVTEPI16_EPI32_M64( &x_ptr[ subfr_length - n + k - 1 ] ); | ||
224 | |||
225 | xmm_x_ptr_n_k_x2x0 = _mm_shuffle_epi32( xmm_x_ptr_n_k_x2x0, _MM_SHUFFLE( 0, 1, 2, 3 ) ); | ||
226 | |||
227 | xmm_x_ptr_n_k_x2x0 = _mm_slli_epi32( xmm_x_ptr_n_k_x2x0, -rshifts - 1 ); | ||
228 | xmm_x_ptr_sub_x2x0 = _mm_slli_epi32( xmm_x_ptr_sub_x2x0, -rshifts - 1 ); | ||
229 | |||
230 | /* equal shift right 4 bytes, xmm_x_ptr_n_k_x3x1 = _mm_srli_si128(xmm_x_ptr_n_k_x2x0, 4)*/ | ||
231 | xmm_x_ptr_n_k_x3x1 = _mm_shuffle_epi32( xmm_x_ptr_n_k_x2x0, _MM_SHUFFLE( 0, 3, 2, 1 ) ); | ||
232 | xmm_x_ptr_sub_x3x1 = _mm_shuffle_epi32( xmm_x_ptr_sub_x2x0, _MM_SHUFFLE( 0, 3, 2, 1 ) ); | ||
233 | |||
234 | xmm_x_ptr_n_k_x2x0 = _mm_mul_epi32( xmm_x_ptr_n_k_x2x0, xmm_tmp1 ); | ||
235 | xmm_x_ptr_n_k_x3x1 = _mm_mul_epi32( xmm_x_ptr_n_k_x3x1, xmm_tmp1 ); | ||
236 | xmm_x_ptr_sub_x2x0 = _mm_mul_epi32( xmm_x_ptr_sub_x2x0, xmm_tmp2 ); | ||
237 | xmm_x_ptr_sub_x3x1 = _mm_mul_epi32( xmm_x_ptr_sub_x3x1, xmm_tmp2 ); | ||
238 | |||
239 | xmm_x_ptr_n_k_x2x0 = _mm_srli_epi64( xmm_x_ptr_n_k_x2x0, 16 ); | ||
240 | xmm_x_ptr_n_k_x3x1 = _mm_slli_epi64( xmm_x_ptr_n_k_x3x1, 16 ); | ||
241 | xmm_x_ptr_sub_x2x0 = _mm_srli_epi64( xmm_x_ptr_sub_x2x0, 16 ); | ||
242 | xmm_x_ptr_sub_x3x1 = _mm_slli_epi64( xmm_x_ptr_sub_x3x1, 16 ); | ||
243 | |||
244 | xmm_x_ptr_n_k_x2x0 = _mm_blend_epi16( xmm_x_ptr_n_k_x2x0, xmm_x_ptr_n_k_x3x1, 0xCC ); | ||
245 | xmm_x_ptr_sub_x2x0 = _mm_blend_epi16( xmm_x_ptr_sub_x2x0, xmm_x_ptr_sub_x3x1, 0xCC ); | ||
246 | |||
247 | X1_3210 = _mm_loadu_si128( (__m128i *)&CAf[ k ] ); | ||
248 | PTR_3210 = _mm_loadu_si128( (__m128i *)&CAb[ k ] ); | ||
249 | |||
250 | X1_3210 = _mm_add_epi32( X1_3210, xmm_x_ptr_n_k_x2x0 ); | ||
251 | PTR_3210 = _mm_add_epi32( PTR_3210, xmm_x_ptr_sub_x2x0 ); | ||
252 | |||
253 | _mm_storeu_si128( (__m128i *)&CAf[ k ], X1_3210 ); | ||
254 | _mm_storeu_si128( (__m128i *)&CAb[ k ], PTR_3210 ); | ||
255 | } | ||
256 | |||
257 | for( ; k <= n; k++ ) { | ||
258 | CAf[ k ] = silk_SMLAWW( CAf[ k ], tmp1, | ||
259 | silk_LSHIFT32( (opus_int32)x_ptr[ n - k ], -rshifts - 1 ) ); /* Q( -rshift ) */ | ||
260 | CAb[ k ] = silk_SMLAWW( CAb[ k ], tmp2, | ||
261 | silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n + k - 1 ], -rshifts - 1 ) ); /* Q( -rshift ) */ | ||
262 | } | ||
263 | } | ||
264 | } | ||
265 | } | ||
266 | |||
267 | /* Calculate nominator and denominator for the next order reflection (parcor) coefficient */ | ||
268 | tmp1 = C_first_row[ n ]; /* Q( -rshifts ) */ | ||
269 | tmp2 = C_last_row[ n ]; /* Q( -rshifts ) */ | ||
270 | num = 0; /* Q( -rshifts ) */ | ||
271 | nrg = silk_ADD32( CAb[ 0 ], CAf[ 0 ] ); /* Q( 1-rshifts ) */ | ||
272 | for( k = 0; k < n; k++ ) { | ||
273 | Atmp_QA = Af_QA[ k ]; | ||
274 | lz = silk_CLZ32( silk_abs( Atmp_QA ) ) - 1; | ||
275 | lz = silk_min( 32 - QA, lz ); | ||
276 | Atmp1 = silk_LSHIFT32( Atmp_QA, lz ); /* Q( QA + lz ) */ | ||
277 | |||
278 | tmp1 = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( C_last_row[ n - k - 1 ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts ) */ | ||
279 | tmp2 = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( C_first_row[ n - k - 1 ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts ) */ | ||
280 | num = silk_ADD_LSHIFT32( num, silk_SMMUL( CAb[ n - k ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts ) */ | ||
281 | nrg = silk_ADD_LSHIFT32( nrg, silk_SMMUL( silk_ADD32( CAb[ k + 1 ], CAf[ k + 1 ] ), | ||
282 | Atmp1 ), 32 - QA - lz ); /* Q( 1-rshifts ) */ | ||
283 | } | ||
284 | CAf[ n + 1 ] = tmp1; /* Q( -rshifts ) */ | ||
285 | CAb[ n + 1 ] = tmp2; /* Q( -rshifts ) */ | ||
286 | num = silk_ADD32( num, tmp2 ); /* Q( -rshifts ) */ | ||
287 | num = silk_LSHIFT32( -num, 1 ); /* Q( 1-rshifts ) */ | ||
288 | |||
289 | /* Calculate the next order reflection (parcor) coefficient */ | ||
290 | if( silk_abs( num ) < nrg ) { | ||
291 | rc_Q31 = silk_DIV32_varQ( num, nrg, 31 ); | ||
292 | } else { | ||
293 | rc_Q31 = ( num > 0 ) ? silk_int32_MAX : silk_int32_MIN; | ||
294 | } | ||
295 | |||
296 | /* Update inverse prediction gain */ | ||
297 | tmp1 = ( (opus_int32)1 << 30 ) - silk_SMMUL( rc_Q31, rc_Q31 ); | ||
298 | tmp1 = silk_LSHIFT( silk_SMMUL( invGain_Q30, tmp1 ), 2 ); | ||
299 | if( tmp1 <= minInvGain_Q30 ) { | ||
300 | /* Max prediction gain exceeded; set reflection coefficient such that max prediction gain is exactly hit */ | ||
301 | tmp2 = ( (opus_int32)1 << 30 ) - silk_DIV32_varQ( minInvGain_Q30, invGain_Q30, 30 ); /* Q30 */ | ||
302 | rc_Q31 = silk_SQRT_APPROX( tmp2 ); /* Q15 */ | ||
303 | if( rc_Q31 > 0 ) { | ||
304 | /* Newton-Raphson iteration */ | ||
305 | rc_Q31 = silk_RSHIFT32( rc_Q31 + silk_DIV32( tmp2, rc_Q31 ), 1 ); /* Q15 */ | ||
306 | rc_Q31 = silk_LSHIFT32( rc_Q31, 16 ); /* Q31 */ | ||
307 | if( num < 0 ) { | ||
308 | /* Ensure adjusted reflection coefficients has the original sign */ | ||
309 | rc_Q31 = -rc_Q31; | ||
310 | } | ||
311 | } | ||
312 | invGain_Q30 = minInvGain_Q30; | ||
313 | reached_max_gain = 1; | ||
314 | } else { | ||
315 | invGain_Q30 = tmp1; | ||
316 | } | ||
317 | |||
318 | /* Update the AR coefficients */ | ||
319 | for( k = 0; k < (n + 1) >> 1; k++ ) { | ||
320 | tmp1 = Af_QA[ k ]; /* QA */ | ||
321 | tmp2 = Af_QA[ n - k - 1 ]; /* QA */ | ||
322 | Af_QA[ k ] = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( tmp2, rc_Q31 ), 1 ); /* QA */ | ||
323 | Af_QA[ n - k - 1 ] = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( tmp1, rc_Q31 ), 1 ); /* QA */ | ||
324 | } | ||
325 | Af_QA[ n ] = silk_RSHIFT32( rc_Q31, 31 - QA ); /* QA */ | ||
326 | |||
327 | if( reached_max_gain ) { | ||
328 | /* Reached max prediction gain; set remaining coefficients to zero and exit loop */ | ||
329 | for( k = n + 1; k < D; k++ ) { | ||
330 | Af_QA[ k ] = 0; | ||
331 | } | ||
332 | break; | ||
333 | } | ||
334 | |||
335 | /* Update C * Af and C * Ab */ | ||
336 | for( k = 0; k <= n + 1; k++ ) { | ||
337 | tmp1 = CAf[ k ]; /* Q( -rshifts ) */ | ||
338 | tmp2 = CAb[ n - k + 1 ]; /* Q( -rshifts ) */ | ||
339 | CAf[ k ] = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( tmp2, rc_Q31 ), 1 ); /* Q( -rshifts ) */ | ||
340 | CAb[ n - k + 1 ] = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( tmp1, rc_Q31 ), 1 ); /* Q( -rshifts ) */ | ||
341 | } | ||
342 | } | ||
343 | |||
344 | if( reached_max_gain ) { | ||
345 | for( k = 0; k < D; k++ ) { | ||
346 | /* Scale coefficients */ | ||
347 | A_Q16[ k ] = -silk_RSHIFT_ROUND( Af_QA[ k ], QA - 16 ); | ||
348 | } | ||
349 | /* Subtract energy of preceding samples from C0 */ | ||
350 | if( rshifts > 0 ) { | ||
351 | for( s = 0; s < nb_subfr; s++ ) { | ||
352 | x_ptr = x + s * subfr_length; | ||
353 | C0 -= (opus_int32)silk_RSHIFT64( silk_inner_prod16_aligned_64( x_ptr, x_ptr, D, arch ), rshifts ); | ||
354 | } | ||
355 | } else { | ||
356 | for( s = 0; s < nb_subfr; s++ ) { | ||
357 | x_ptr = x + s * subfr_length; | ||
358 | C0 -= silk_LSHIFT32( silk_inner_prod_aligned( x_ptr, x_ptr, D, arch ), -rshifts ); | ||
359 | } | ||
360 | } | ||
361 | /* Approximate residual energy */ | ||
362 | *res_nrg = silk_LSHIFT( silk_SMMUL( invGain_Q30, C0 ), 2 ); | ||
363 | *res_nrg_Q = -rshifts; | ||
364 | } else { | ||
365 | /* Return residual energy */ | ||
366 | nrg = CAf[ 0 ]; /* Q( -rshifts ) */ | ||
367 | tmp1 = (opus_int32)1 << 16; /* Q16 */ | ||
368 | for( k = 0; k < D; k++ ) { | ||
369 | Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 16 ); /* Q16 */ | ||
370 | nrg = silk_SMLAWW( nrg, CAf[ k + 1 ], Atmp1 ); /* Q( -rshifts ) */ | ||
371 | tmp1 = silk_SMLAWW( tmp1, Atmp1, Atmp1 ); /* Q16 */ | ||
372 | A_Q16[ k ] = -Atmp1; | ||
373 | } | ||
374 | *res_nrg = silk_SMLAWW( nrg, silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ), -tmp1 );/* Q( -rshifts ) */ | ||
375 | *res_nrg_Q = -rshifts; | ||
376 | } | ||
377 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/x86/prefilter_FIX_sse.c b/lib/rbcodec/codecs/libopus/silk/fixed/x86/prefilter_FIX_sse.c new file mode 100644 index 0000000000..555432cd96 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/fixed/x86/prefilter_FIX_sse.c | |||
@@ -0,0 +1,160 @@ | |||
1 | /* Copyright (c) 2014, Cisco Systems, INC | ||
2 | Written by XiangMingZhu WeiZhou MinPeng YanWang | ||
3 | |||
4 | Redistribution and use in source and binary forms, with or without | ||
5 | modification, are permitted provided that the following conditions | ||
6 | are met: | ||
7 | |||
8 | - Redistributions of source code must retain the above copyright | ||
9 | notice, this list of conditions and the following disclaimer. | ||
10 | |||
11 | - Redistributions in binary form must reproduce the above copyright | ||
12 | notice, this list of conditions and the following disclaimer in the | ||
13 | documentation and/or other materials provided with the distribution. | ||
14 | |||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
16 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
17 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
18 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER | ||
19 | OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
20 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
21 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
22 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
23 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
24 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include <xmmintrin.h> | ||
33 | #include <emmintrin.h> | ||
34 | #include <smmintrin.h> | ||
35 | #include "main.h" | ||
36 | #include "celt/x86/x86cpu.h" | ||
37 | |||
38 | void silk_warped_LPC_analysis_filter_FIX_sse4_1( | ||
39 | opus_int32 state[], /* I/O State [order + 1] */ | ||
40 | opus_int32 res_Q2[], /* O Residual signal [length] */ | ||
41 | const opus_int16 coef_Q13[], /* I Coefficients [order] */ | ||
42 | const opus_int16 input[], /* I Input signal [length] */ | ||
43 | const opus_int16 lambda_Q16, /* I Warping factor */ | ||
44 | const opus_int length, /* I Length of input signal */ | ||
45 | const opus_int order /* I Filter order (even) */ | ||
46 | ) | ||
47 | { | ||
48 | opus_int n, i; | ||
49 | opus_int32 acc_Q11, tmp1, tmp2; | ||
50 | |||
51 | /* Order must be even */ | ||
52 | celt_assert( ( order & 1 ) == 0 ); | ||
53 | |||
54 | if (order == 10) | ||
55 | { | ||
56 | if (0 == lambda_Q16) | ||
57 | { | ||
58 | __m128i coef_Q13_3210, coef_Q13_7654; | ||
59 | __m128i coef_Q13_0123, coef_Q13_4567; | ||
60 | __m128i state_0123, state_4567; | ||
61 | __m128i xmm_product1, xmm_product2; | ||
62 | __m128i xmm_tempa, xmm_tempb; | ||
63 | |||
64 | register opus_int32 sum; | ||
65 | register opus_int32 state_8, state_9, state_a; | ||
66 | register opus_int64 coef_Q13_8, coef_Q13_9; | ||
67 | |||
68 | celt_assert( length > 0 ); | ||
69 | |||
70 | coef_Q13_3210 = OP_CVTEPI16_EPI32_M64( &coef_Q13[ 0 ] ); | ||
71 | coef_Q13_7654 = OP_CVTEPI16_EPI32_M64( &coef_Q13[ 4 ] ); | ||
72 | |||
73 | coef_Q13_0123 = _mm_shuffle_epi32( coef_Q13_3210, _MM_SHUFFLE( 0, 1, 2, 3 ) ); | ||
74 | coef_Q13_4567 = _mm_shuffle_epi32( coef_Q13_7654, _MM_SHUFFLE( 0, 1, 2, 3 ) ); | ||
75 | |||
76 | coef_Q13_8 = (opus_int64) coef_Q13[ 8 ]; | ||
77 | coef_Q13_9 = (opus_int64) coef_Q13[ 9 ]; | ||
78 | |||
79 | state_0123 = _mm_loadu_si128( (__m128i *)(&state[ 0 ] ) ); | ||
80 | state_4567 = _mm_loadu_si128( (__m128i *)(&state[ 4 ] ) ); | ||
81 | |||
82 | state_0123 = _mm_shuffle_epi32( state_0123, _MM_SHUFFLE( 0, 1, 2, 3 ) ); | ||
83 | state_4567 = _mm_shuffle_epi32( state_4567, _MM_SHUFFLE( 0, 1, 2, 3 ) ); | ||
84 | |||
85 | state_8 = state[ 8 ]; | ||
86 | state_9 = state[ 9 ]; | ||
87 | state_a = 0; | ||
88 | |||
89 | for( n = 0; n < length; n++ ) | ||
90 | { | ||
91 | xmm_product1 = _mm_mul_epi32( coef_Q13_0123, state_0123 ); /* 64-bit multiply, only 2 pairs */ | ||
92 | xmm_product2 = _mm_mul_epi32( coef_Q13_4567, state_4567 ); | ||
93 | |||
94 | xmm_tempa = _mm_shuffle_epi32( state_0123, _MM_SHUFFLE( 0, 1, 2, 3 ) ); | ||
95 | xmm_tempb = _mm_shuffle_epi32( state_4567, _MM_SHUFFLE( 0, 1, 2, 3 ) ); | ||
96 | |||
97 | xmm_product1 = _mm_srli_epi64( xmm_product1, 16 ); /* >> 16, zero extending works */ | ||
98 | xmm_product2 = _mm_srli_epi64( xmm_product2, 16 ); | ||
99 | |||
100 | xmm_tempa = _mm_mul_epi32( coef_Q13_3210, xmm_tempa ); | ||
101 | xmm_tempb = _mm_mul_epi32( coef_Q13_7654, xmm_tempb ); | ||
102 | |||
103 | xmm_tempa = _mm_srli_epi64( xmm_tempa, 16 ); | ||
104 | xmm_tempb = _mm_srli_epi64( xmm_tempb, 16 ); | ||
105 | |||
106 | xmm_tempa = _mm_add_epi32( xmm_tempa, xmm_product1 ); | ||
107 | xmm_tempb = _mm_add_epi32( xmm_tempb, xmm_product2 ); | ||
108 | xmm_tempa = _mm_add_epi32( xmm_tempa, xmm_tempb ); | ||
109 | |||
110 | sum = (opus_int32)((coef_Q13_8 * state_8) >> 16); | ||
111 | sum += (opus_int32)((coef_Q13_9 * state_9) >> 16); | ||
112 | |||
113 | xmm_tempa = _mm_add_epi32( xmm_tempa, _mm_shuffle_epi32( xmm_tempa, _MM_SHUFFLE( 0, 0, 0, 2 ) ) ); | ||
114 | sum += _mm_cvtsi128_si32( xmm_tempa); | ||
115 | res_Q2[ n ] = silk_LSHIFT( (opus_int32)input[ n ], 2 ) - silk_RSHIFT_ROUND( ( 5 + sum ), 9); | ||
116 | |||
117 | /* move right */ | ||
118 | state_a = state_9; | ||
119 | state_9 = state_8; | ||
120 | state_8 = _mm_cvtsi128_si32( state_4567 ); | ||
121 | state_4567 = _mm_alignr_epi8( state_0123, state_4567, 4 ); | ||
122 | |||
123 | state_0123 = _mm_alignr_epi8( _mm_cvtsi32_si128( silk_LSHIFT( input[ n ], 14 ) ), state_0123, 4 ); | ||
124 | } | ||
125 | |||
126 | _mm_storeu_si128( (__m128i *)( &state[ 0 ] ), _mm_shuffle_epi32( state_0123, _MM_SHUFFLE( 0, 1, 2, 3 ) ) ); | ||
127 | _mm_storeu_si128( (__m128i *)( &state[ 4 ] ), _mm_shuffle_epi32( state_4567, _MM_SHUFFLE( 0, 1, 2, 3 ) ) ); | ||
128 | state[ 8 ] = state_8; | ||
129 | state[ 9 ] = state_9; | ||
130 | state[ 10 ] = state_a; | ||
131 | |||
132 | return; | ||
133 | } | ||
134 | } | ||
135 | |||
136 | for( n = 0; n < length; n++ ) { | ||
137 | /* Output of lowpass section */ | ||
138 | tmp2 = silk_SMLAWB( state[ 0 ], state[ 1 ], lambda_Q16 ); | ||
139 | state[ 0 ] = silk_LSHIFT( input[ n ], 14 ); | ||
140 | /* Output of allpass section */ | ||
141 | tmp1 = silk_SMLAWB( state[ 1 ], state[ 2 ] - tmp2, lambda_Q16 ); | ||
142 | state[ 1 ] = tmp2; | ||
143 | acc_Q11 = silk_RSHIFT( order, 1 ); | ||
144 | acc_Q11 = silk_SMLAWB( acc_Q11, tmp2, coef_Q13[ 0 ] ); | ||
145 | /* Loop over allpass sections */ | ||
146 | for( i = 2; i < order; i += 2 ) { | ||
147 | /* Output of allpass section */ | ||
148 | tmp2 = silk_SMLAWB( state[ i ], state[ i + 1 ] - tmp1, lambda_Q16 ); | ||
149 | state[ i ] = tmp1; | ||
150 | acc_Q11 = silk_SMLAWB( acc_Q11, tmp1, coef_Q13[ i - 1 ] ); | ||
151 | /* Output of allpass section */ | ||
152 | tmp1 = silk_SMLAWB( state[ i + 1 ], state[ i + 2 ] - tmp2, lambda_Q16 ); | ||
153 | state[ i + 1 ] = tmp2; | ||
154 | acc_Q11 = silk_SMLAWB( acc_Q11, tmp2, coef_Q13[ i ] ); | ||
155 | } | ||
156 | state[ order ] = tmp1; | ||
157 | acc_Q11 = silk_SMLAWB( acc_Q11, tmp1, coef_Q13[ order - 1 ] ); | ||
158 | res_Q2[ n ] = silk_LSHIFT( (opus_int32)input[ n ], 2 ) - silk_RSHIFT_ROUND( acc_Q11, 9 ); | ||
159 | } | ||
160 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/x86/vector_ops_FIX_sse4_1.c b/lib/rbcodec/codecs/libopus/silk/fixed/x86/vector_ops_FIX_sse4_1.c new file mode 100644 index 0000000000..c1e90564d0 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/fixed/x86/vector_ops_FIX_sse4_1.c | |||
@@ -0,0 +1,88 @@ | |||
1 | /* Copyright (c) 2014, Cisco Systems, INC | ||
2 | Written by XiangMingZhu WeiZhou MinPeng YanWang | ||
3 | |||
4 | Redistribution and use in source and binary forms, with or without | ||
5 | modification, are permitted provided that the following conditions | ||
6 | are met: | ||
7 | |||
8 | - Redistributions of source code must retain the above copyright | ||
9 | notice, this list of conditions and the following disclaimer. | ||
10 | |||
11 | - Redistributions in binary form must reproduce the above copyright | ||
12 | notice, this list of conditions and the following disclaimer in the | ||
13 | documentation and/or other materials provided with the distribution. | ||
14 | |||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
16 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
17 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
18 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER | ||
19 | OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
20 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
21 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
22 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
23 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
24 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include <xmmintrin.h> | ||
33 | #include <emmintrin.h> | ||
34 | #include <smmintrin.h> | ||
35 | #include "main.h" | ||
36 | |||
37 | #include "SigProc_FIX.h" | ||
38 | #include "pitch.h" | ||
39 | |||
40 | opus_int64 silk_inner_prod16_aligned_64_sse4_1( | ||
41 | const opus_int16 *inVec1, /* I input vector 1 */ | ||
42 | const opus_int16 *inVec2, /* I input vector 2 */ | ||
43 | const opus_int len /* I vector lengths */ | ||
44 | ) | ||
45 | { | ||
46 | opus_int i, dataSize8; | ||
47 | opus_int64 sum; | ||
48 | |||
49 | __m128i xmm_tempa; | ||
50 | __m128i inVec1_76543210, acc1; | ||
51 | __m128i inVec2_76543210, acc2; | ||
52 | |||
53 | sum = 0; | ||
54 | dataSize8 = len & ~7; | ||
55 | |||
56 | acc1 = _mm_setzero_si128(); | ||
57 | acc2 = _mm_setzero_si128(); | ||
58 | |||
59 | for( i = 0; i < dataSize8; i += 8 ) { | ||
60 | inVec1_76543210 = _mm_loadu_si128( (__m128i *)(&inVec1[i + 0] ) ); | ||
61 | inVec2_76543210 = _mm_loadu_si128( (__m128i *)(&inVec2[i + 0] ) ); | ||
62 | |||
63 | /* only when all 4 operands are -32768 (0x8000), this results in wrap around */ | ||
64 | inVec1_76543210 = _mm_madd_epi16( inVec1_76543210, inVec2_76543210 ); | ||
65 | |||
66 | xmm_tempa = _mm_cvtepi32_epi64( inVec1_76543210 ); | ||
67 | /* equal shift right 8 bytes */ | ||
68 | inVec1_76543210 = _mm_shuffle_epi32( inVec1_76543210, _MM_SHUFFLE( 0, 0, 3, 2 ) ); | ||
69 | inVec1_76543210 = _mm_cvtepi32_epi64( inVec1_76543210 ); | ||
70 | |||
71 | acc1 = _mm_add_epi64( acc1, xmm_tempa ); | ||
72 | acc2 = _mm_add_epi64( acc2, inVec1_76543210 ); | ||
73 | } | ||
74 | |||
75 | acc1 = _mm_add_epi64( acc1, acc2 ); | ||
76 | |||
77 | /* equal shift right 8 bytes */ | ||
78 | acc2 = _mm_shuffle_epi32( acc1, _MM_SHUFFLE( 0, 0, 3, 2 ) ); | ||
79 | acc1 = _mm_add_epi64( acc1, acc2 ); | ||
80 | |||
81 | _mm_storel_epi64( (__m128i *)&sum, acc1 ); | ||
82 | |||
83 | for( ; i < len; i++ ) { | ||
84 | sum = silk_SMLABB( sum, inVec1[ i ], inVec2[ i ] ); | ||
85 | } | ||
86 | |||
87 | return sum; | ||
88 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/float/LPC_analysis_filter_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/LPC_analysis_filter_FLP.c new file mode 100644 index 0000000000..0e1a1fed0f --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/float/LPC_analysis_filter_FLP.c | |||
@@ -0,0 +1,249 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include <stdlib.h> | ||
33 | #include "main_FLP.h" | ||
34 | |||
35 | /************************************************/ | ||
36 | /* LPC analysis filter */ | ||
37 | /* NB! State is kept internally and the */ | ||
38 | /* filter always starts with zero state */ | ||
39 | /* first Order output samples are set to zero */ | ||
40 | /************************************************/ | ||
41 | |||
42 | /* 16th order LPC analysis filter, does not write first 16 samples */ | ||
43 | static OPUS_INLINE void silk_LPC_analysis_filter16_FLP( | ||
44 | silk_float r_LPC[], /* O LPC residual signal */ | ||
45 | const silk_float PredCoef[], /* I LPC coefficients */ | ||
46 | const silk_float s[], /* I Input signal */ | ||
47 | const opus_int length /* I Length of input signal */ | ||
48 | ) | ||
49 | { | ||
50 | opus_int ix; | ||
51 | silk_float LPC_pred; | ||
52 | const silk_float *s_ptr; | ||
53 | |||
54 | for( ix = 16; ix < length; ix++ ) { | ||
55 | s_ptr = &s[ix - 1]; | ||
56 | |||
57 | /* short-term prediction */ | ||
58 | LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] + | ||
59 | s_ptr[ -1 ] * PredCoef[ 1 ] + | ||
60 | s_ptr[ -2 ] * PredCoef[ 2 ] + | ||
61 | s_ptr[ -3 ] * PredCoef[ 3 ] + | ||
62 | s_ptr[ -4 ] * PredCoef[ 4 ] + | ||
63 | s_ptr[ -5 ] * PredCoef[ 5 ] + | ||
64 | s_ptr[ -6 ] * PredCoef[ 6 ] + | ||
65 | s_ptr[ -7 ] * PredCoef[ 7 ] + | ||
66 | s_ptr[ -8 ] * PredCoef[ 8 ] + | ||
67 | s_ptr[ -9 ] * PredCoef[ 9 ] + | ||
68 | s_ptr[ -10 ] * PredCoef[ 10 ] + | ||
69 | s_ptr[ -11 ] * PredCoef[ 11 ] + | ||
70 | s_ptr[ -12 ] * PredCoef[ 12 ] + | ||
71 | s_ptr[ -13 ] * PredCoef[ 13 ] + | ||
72 | s_ptr[ -14 ] * PredCoef[ 14 ] + | ||
73 | s_ptr[ -15 ] * PredCoef[ 15 ]; | ||
74 | |||
75 | /* prediction error */ | ||
76 | r_LPC[ix] = s_ptr[ 1 ] - LPC_pred; | ||
77 | } | ||
78 | } | ||
79 | |||
80 | /* 12th order LPC analysis filter, does not write first 12 samples */ | ||
81 | static OPUS_INLINE void silk_LPC_analysis_filter12_FLP( | ||
82 | silk_float r_LPC[], /* O LPC residual signal */ | ||
83 | const silk_float PredCoef[], /* I LPC coefficients */ | ||
84 | const silk_float s[], /* I Input signal */ | ||
85 | const opus_int length /* I Length of input signal */ | ||
86 | ) | ||
87 | { | ||
88 | opus_int ix; | ||
89 | silk_float LPC_pred; | ||
90 | const silk_float *s_ptr; | ||
91 | |||
92 | for( ix = 12; ix < length; ix++ ) { | ||
93 | s_ptr = &s[ix - 1]; | ||
94 | |||
95 | /* short-term prediction */ | ||
96 | LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] + | ||
97 | s_ptr[ -1 ] * PredCoef[ 1 ] + | ||
98 | s_ptr[ -2 ] * PredCoef[ 2 ] + | ||
99 | s_ptr[ -3 ] * PredCoef[ 3 ] + | ||
100 | s_ptr[ -4 ] * PredCoef[ 4 ] + | ||
101 | s_ptr[ -5 ] * PredCoef[ 5 ] + | ||
102 | s_ptr[ -6 ] * PredCoef[ 6 ] + | ||
103 | s_ptr[ -7 ] * PredCoef[ 7 ] + | ||
104 | s_ptr[ -8 ] * PredCoef[ 8 ] + | ||
105 | s_ptr[ -9 ] * PredCoef[ 9 ] + | ||
106 | s_ptr[ -10 ] * PredCoef[ 10 ] + | ||
107 | s_ptr[ -11 ] * PredCoef[ 11 ]; | ||
108 | |||
109 | /* prediction error */ | ||
110 | r_LPC[ix] = s_ptr[ 1 ] - LPC_pred; | ||
111 | } | ||
112 | } | ||
113 | |||
114 | /* 10th order LPC analysis filter, does not write first 10 samples */ | ||
115 | static OPUS_INLINE void silk_LPC_analysis_filter10_FLP( | ||
116 | silk_float r_LPC[], /* O LPC residual signal */ | ||
117 | const silk_float PredCoef[], /* I LPC coefficients */ | ||
118 | const silk_float s[], /* I Input signal */ | ||
119 | const opus_int length /* I Length of input signal */ | ||
120 | ) | ||
121 | { | ||
122 | opus_int ix; | ||
123 | silk_float LPC_pred; | ||
124 | const silk_float *s_ptr; | ||
125 | |||
126 | for( ix = 10; ix < length; ix++ ) { | ||
127 | s_ptr = &s[ix - 1]; | ||
128 | |||
129 | /* short-term prediction */ | ||
130 | LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] + | ||
131 | s_ptr[ -1 ] * PredCoef[ 1 ] + | ||
132 | s_ptr[ -2 ] * PredCoef[ 2 ] + | ||
133 | s_ptr[ -3 ] * PredCoef[ 3 ] + | ||
134 | s_ptr[ -4 ] * PredCoef[ 4 ] + | ||
135 | s_ptr[ -5 ] * PredCoef[ 5 ] + | ||
136 | s_ptr[ -6 ] * PredCoef[ 6 ] + | ||
137 | s_ptr[ -7 ] * PredCoef[ 7 ] + | ||
138 | s_ptr[ -8 ] * PredCoef[ 8 ] + | ||
139 | s_ptr[ -9 ] * PredCoef[ 9 ]; | ||
140 | |||
141 | /* prediction error */ | ||
142 | r_LPC[ix] = s_ptr[ 1 ] - LPC_pred; | ||
143 | } | ||
144 | } | ||
145 | |||
146 | /* 8th order LPC analysis filter, does not write first 8 samples */ | ||
147 | static OPUS_INLINE void silk_LPC_analysis_filter8_FLP( | ||
148 | silk_float r_LPC[], /* O LPC residual signal */ | ||
149 | const silk_float PredCoef[], /* I LPC coefficients */ | ||
150 | const silk_float s[], /* I Input signal */ | ||
151 | const opus_int length /* I Length of input signal */ | ||
152 | ) | ||
153 | { | ||
154 | opus_int ix; | ||
155 | silk_float LPC_pred; | ||
156 | const silk_float *s_ptr; | ||
157 | |||
158 | for( ix = 8; ix < length; ix++ ) { | ||
159 | s_ptr = &s[ix - 1]; | ||
160 | |||
161 | /* short-term prediction */ | ||
162 | LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] + | ||
163 | s_ptr[ -1 ] * PredCoef[ 1 ] + | ||
164 | s_ptr[ -2 ] * PredCoef[ 2 ] + | ||
165 | s_ptr[ -3 ] * PredCoef[ 3 ] + | ||
166 | s_ptr[ -4 ] * PredCoef[ 4 ] + | ||
167 | s_ptr[ -5 ] * PredCoef[ 5 ] + | ||
168 | s_ptr[ -6 ] * PredCoef[ 6 ] + | ||
169 | s_ptr[ -7 ] * PredCoef[ 7 ]; | ||
170 | |||
171 | /* prediction error */ | ||
172 | r_LPC[ix] = s_ptr[ 1 ] - LPC_pred; | ||
173 | } | ||
174 | } | ||
175 | |||
176 | /* 6th order LPC analysis filter, does not write first 6 samples */ | ||
177 | static OPUS_INLINE void silk_LPC_analysis_filter6_FLP( | ||
178 | silk_float r_LPC[], /* O LPC residual signal */ | ||
179 | const silk_float PredCoef[], /* I LPC coefficients */ | ||
180 | const silk_float s[], /* I Input signal */ | ||
181 | const opus_int length /* I Length of input signal */ | ||
182 | ) | ||
183 | { | ||
184 | opus_int ix; | ||
185 | silk_float LPC_pred; | ||
186 | const silk_float *s_ptr; | ||
187 | |||
188 | for( ix = 6; ix < length; ix++ ) { | ||
189 | s_ptr = &s[ix - 1]; | ||
190 | |||
191 | /* short-term prediction */ | ||
192 | LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] + | ||
193 | s_ptr[ -1 ] * PredCoef[ 1 ] + | ||
194 | s_ptr[ -2 ] * PredCoef[ 2 ] + | ||
195 | s_ptr[ -3 ] * PredCoef[ 3 ] + | ||
196 | s_ptr[ -4 ] * PredCoef[ 4 ] + | ||
197 | s_ptr[ -5 ] * PredCoef[ 5 ]; | ||
198 | |||
199 | /* prediction error */ | ||
200 | r_LPC[ix] = s_ptr[ 1 ] - LPC_pred; | ||
201 | } | ||
202 | } | ||
203 | |||
204 | /************************************************/ | ||
205 | /* LPC analysis filter */ | ||
206 | /* NB! State is kept internally and the */ | ||
207 | /* filter always starts with zero state */ | ||
208 | /* first Order output samples are set to zero */ | ||
209 | /************************************************/ | ||
210 | void silk_LPC_analysis_filter_FLP( | ||
211 | silk_float r_LPC[], /* O LPC residual signal */ | ||
212 | const silk_float PredCoef[], /* I LPC coefficients */ | ||
213 | const silk_float s[], /* I Input signal */ | ||
214 | const opus_int length, /* I Length of input signal */ | ||
215 | const opus_int Order /* I LPC order */ | ||
216 | ) | ||
217 | { | ||
218 | celt_assert( Order <= length ); | ||
219 | |||
220 | switch( Order ) { | ||
221 | case 6: | ||
222 | silk_LPC_analysis_filter6_FLP( r_LPC, PredCoef, s, length ); | ||
223 | break; | ||
224 | |||
225 | case 8: | ||
226 | silk_LPC_analysis_filter8_FLP( r_LPC, PredCoef, s, length ); | ||
227 | break; | ||
228 | |||
229 | case 10: | ||
230 | silk_LPC_analysis_filter10_FLP( r_LPC, PredCoef, s, length ); | ||
231 | break; | ||
232 | |||
233 | case 12: | ||
234 | silk_LPC_analysis_filter12_FLP( r_LPC, PredCoef, s, length ); | ||
235 | break; | ||
236 | |||
237 | case 16: | ||
238 | silk_LPC_analysis_filter16_FLP( r_LPC, PredCoef, s, length ); | ||
239 | break; | ||
240 | |||
241 | default: | ||
242 | celt_assert( 0 ); | ||
243 | break; | ||
244 | } | ||
245 | |||
246 | /* Set first Order output samples to zero */ | ||
247 | silk_memset( r_LPC, 0, Order * sizeof( silk_float ) ); | ||
248 | } | ||
249 | |||
diff --git a/lib/rbcodec/codecs/libopus/silk/float/LPC_inv_pred_gain_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/LPC_inv_pred_gain_FLP.c new file mode 100644 index 0000000000..2be2122d61 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/float/LPC_inv_pred_gain_FLP.c | |||
@@ -0,0 +1,73 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "SigProc_FIX.h" | ||
33 | #include "SigProc_FLP.h" | ||
34 | #include "define.h" | ||
35 | |||
36 | /* compute inverse of LPC prediction gain, and */ | ||
37 | /* test if LPC coefficients are stable (all poles within unit circle) */ | ||
38 | /* this code is based on silk_a2k_FLP() */ | ||
39 | silk_float silk_LPC_inverse_pred_gain_FLP( /* O return inverse prediction gain, energy domain */ | ||
40 | const silk_float *A, /* I prediction coefficients [order] */ | ||
41 | opus_int32 order /* I prediction order */ | ||
42 | ) | ||
43 | { | ||
44 | opus_int k, n; | ||
45 | double invGain, rc, rc_mult1, rc_mult2, tmp1, tmp2; | ||
46 | silk_float Atmp[ SILK_MAX_ORDER_LPC ]; | ||
47 | |||
48 | silk_memcpy( Atmp, A, order * sizeof(silk_float) ); | ||
49 | |||
50 | invGain = 1.0; | ||
51 | for( k = order - 1; k > 0; k-- ) { | ||
52 | rc = -Atmp[ k ]; | ||
53 | rc_mult1 = 1.0f - rc * rc; | ||
54 | invGain *= rc_mult1; | ||
55 | if( invGain * MAX_PREDICTION_POWER_GAIN < 1.0f ) { | ||
56 | return 0.0f; | ||
57 | } | ||
58 | rc_mult2 = 1.0f / rc_mult1; | ||
59 | for( n = 0; n < (k + 1) >> 1; n++ ) { | ||
60 | tmp1 = Atmp[ n ]; | ||
61 | tmp2 = Atmp[ k - n - 1 ]; | ||
62 | Atmp[ n ] = (silk_float)( ( tmp1 - tmp2 * rc ) * rc_mult2 ); | ||
63 | Atmp[ k - n - 1 ] = (silk_float)( ( tmp2 - tmp1 * rc ) * rc_mult2 ); | ||
64 | } | ||
65 | } | ||
66 | rc = -Atmp[ 0 ]; | ||
67 | rc_mult1 = 1.0f - rc * rc; | ||
68 | invGain *= rc_mult1; | ||
69 | if( invGain * MAX_PREDICTION_POWER_GAIN < 1.0f ) { | ||
70 | return 0.0f; | ||
71 | } | ||
72 | return (silk_float)invGain; | ||
73 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/float/LTP_analysis_filter_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/LTP_analysis_filter_FLP.c new file mode 100644 index 0000000000..849b7c1c52 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/float/LTP_analysis_filter_FLP.c | |||
@@ -0,0 +1,75 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main_FLP.h" | ||
33 | |||
34 | void silk_LTP_analysis_filter_FLP( | ||
35 | silk_float *LTP_res, /* O LTP res MAX_NB_SUBFR*(pre_lgth+subfr_lngth) */ | ||
36 | const silk_float *x, /* I Input signal, with preceding samples */ | ||
37 | const silk_float B[ LTP_ORDER * MAX_NB_SUBFR ], /* I LTP coefficients for each subframe */ | ||
38 | const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ | ||
39 | const silk_float invGains[ MAX_NB_SUBFR ], /* I Inverse quantization gains */ | ||
40 | const opus_int subfr_length, /* I Length of each subframe */ | ||
41 | const opus_int nb_subfr, /* I number of subframes */ | ||
42 | const opus_int pre_length /* I Preceding samples for each subframe */ | ||
43 | ) | ||
44 | { | ||
45 | const silk_float *x_ptr, *x_lag_ptr; | ||
46 | silk_float Btmp[ LTP_ORDER ]; | ||
47 | silk_float *LTP_res_ptr; | ||
48 | silk_float inv_gain; | ||
49 | opus_int k, i, j; | ||
50 | |||
51 | x_ptr = x; | ||
52 | LTP_res_ptr = LTP_res; | ||
53 | for( k = 0; k < nb_subfr; k++ ) { | ||
54 | x_lag_ptr = x_ptr - pitchL[ k ]; | ||
55 | inv_gain = invGains[ k ]; | ||
56 | for( i = 0; i < LTP_ORDER; i++ ) { | ||
57 | Btmp[ i ] = B[ k * LTP_ORDER + i ]; | ||
58 | } | ||
59 | |||
60 | /* LTP analysis FIR filter */ | ||
61 | for( i = 0; i < subfr_length + pre_length; i++ ) { | ||
62 | LTP_res_ptr[ i ] = x_ptr[ i ]; | ||
63 | /* Subtract long-term prediction */ | ||
64 | for( j = 0; j < LTP_ORDER; j++ ) { | ||
65 | LTP_res_ptr[ i ] -= Btmp[ j ] * x_lag_ptr[ LTP_ORDER / 2 - j ]; | ||
66 | } | ||
67 | LTP_res_ptr[ i ] *= inv_gain; | ||
68 | x_lag_ptr++; | ||
69 | } | ||
70 | |||
71 | /* Update pointers */ | ||
72 | LTP_res_ptr += subfr_length + pre_length; | ||
73 | x_ptr += subfr_length; | ||
74 | } | ||
75 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/float/LTP_scale_ctrl_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/LTP_scale_ctrl_FLP.c new file mode 100644 index 0000000000..8dbe29d0fa --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/float/LTP_scale_ctrl_FLP.c | |||
@@ -0,0 +1,52 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main_FLP.h" | ||
33 | |||
34 | void silk_LTP_scale_ctrl_FLP( | ||
35 | silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ | ||
36 | silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ | ||
37 | opus_int condCoding /* I The type of conditional coding to use */ | ||
38 | ) | ||
39 | { | ||
40 | opus_int round_loss; | ||
41 | |||
42 | if( condCoding == CODE_INDEPENDENTLY ) { | ||
43 | /* Only scale if first frame in packet */ | ||
44 | round_loss = psEnc->sCmn.PacketLoss_perc + psEnc->sCmn.nFramesPerPacket; | ||
45 | psEnc->sCmn.indices.LTP_scaleIndex = (opus_int8)silk_LIMIT( round_loss * psEncCtrl->LTPredCodGain * 0.1f, 0.0f, 2.0f ); | ||
46 | } else { | ||
47 | /* Default is minimum scaling */ | ||
48 | psEnc->sCmn.indices.LTP_scaleIndex = 0; | ||
49 | } | ||
50 | |||
51 | psEncCtrl->LTP_scale = (silk_float)silk_LTPScales_table_Q14[ psEnc->sCmn.indices.LTP_scaleIndex ] / 16384.0f; | ||
52 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/float/SigProc_FLP.h b/lib/rbcodec/codecs/libopus/silk/float/SigProc_FLP.h new file mode 100644 index 0000000000..953de8b09e --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/float/SigProc_FLP.h | |||
@@ -0,0 +1,197 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifndef SILK_SIGPROC_FLP_H | ||
29 | #define SILK_SIGPROC_FLP_H | ||
30 | |||
31 | #include "SigProc_FIX.h" | ||
32 | #include "float_cast.h" | ||
33 | #include <math.h> | ||
34 | |||
35 | #ifdef __cplusplus | ||
36 | extern "C" | ||
37 | { | ||
38 | #endif | ||
39 | |||
40 | /********************************************************************/ | ||
41 | /* SIGNAL PROCESSING FUNCTIONS */ | ||
42 | /********************************************************************/ | ||
43 | |||
44 | /* Chirp (bw expand) LP AR filter */ | ||
45 | void silk_bwexpander_FLP( | ||
46 | silk_float *ar, /* I/O AR filter to be expanded (without leading 1) */ | ||
47 | const opus_int d, /* I length of ar */ | ||
48 | const silk_float chirp /* I chirp factor (typically in range (0..1) ) */ | ||
49 | ); | ||
50 | |||
51 | /* compute inverse of LPC prediction gain, and */ | ||
52 | /* test if LPC coefficients are stable (all poles within unit circle) */ | ||
53 | /* this code is based on silk_FLP_a2k() */ | ||
54 | silk_float silk_LPC_inverse_pred_gain_FLP( /* O return inverse prediction gain, energy domain */ | ||
55 | const silk_float *A, /* I prediction coefficients [order] */ | ||
56 | opus_int32 order /* I prediction order */ | ||
57 | ); | ||
58 | |||
59 | silk_float silk_schur_FLP( /* O returns residual energy */ | ||
60 | silk_float refl_coef[], /* O reflection coefficients (length order) */ | ||
61 | const silk_float auto_corr[], /* I autocorrelation sequence (length order+1) */ | ||
62 | opus_int order /* I order */ | ||
63 | ); | ||
64 | |||
65 | void silk_k2a_FLP( | ||
66 | silk_float *A, /* O prediction coefficients [order] */ | ||
67 | const silk_float *rc, /* I reflection coefficients [order] */ | ||
68 | opus_int32 order /* I prediction order */ | ||
69 | ); | ||
70 | |||
71 | /* compute autocorrelation */ | ||
72 | void silk_autocorrelation_FLP( | ||
73 | silk_float *results, /* O result (length correlationCount) */ | ||
74 | const silk_float *inputData, /* I input data to correlate */ | ||
75 | opus_int inputDataSize, /* I length of input */ | ||
76 | opus_int correlationCount /* I number of correlation taps to compute */ | ||
77 | ); | ||
78 | |||
79 | opus_int silk_pitch_analysis_core_FLP( /* O Voicing estimate: 0 voiced, 1 unvoiced */ | ||
80 | const silk_float *frame, /* I Signal of length PE_FRAME_LENGTH_MS*Fs_kHz */ | ||
81 | opus_int *pitch_out, /* O Pitch lag values [nb_subfr] */ | ||
82 | opus_int16 *lagIndex, /* O Lag Index */ | ||
83 | opus_int8 *contourIndex, /* O Pitch contour Index */ | ||
84 | silk_float *LTPCorr, /* I/O Normalized correlation; input: value from previous frame */ | ||
85 | opus_int prevLag, /* I Last lag of previous frame; set to zero is unvoiced */ | ||
86 | const silk_float search_thres1, /* I First stage threshold for lag candidates 0 - 1 */ | ||
87 | const silk_float search_thres2, /* I Final threshold for lag candidates 0 - 1 */ | ||
88 | const opus_int Fs_kHz, /* I sample frequency (kHz) */ | ||
89 | const opus_int complexity, /* I Complexity setting, 0-2, where 2 is highest */ | ||
90 | const opus_int nb_subfr, /* I Number of 5 ms subframes */ | ||
91 | int arch /* I Run-time architecture */ | ||
92 | ); | ||
93 | |||
94 | void silk_insertion_sort_decreasing_FLP( | ||
95 | silk_float *a, /* I/O Unsorted / Sorted vector */ | ||
96 | opus_int *idx, /* O Index vector for the sorted elements */ | ||
97 | const opus_int L, /* I Vector length */ | ||
98 | const opus_int K /* I Number of correctly sorted positions */ | ||
99 | ); | ||
100 | |||
101 | /* Compute reflection coefficients from input signal */ | ||
102 | silk_float silk_burg_modified_FLP( /* O returns residual energy */ | ||
103 | silk_float A[], /* O prediction coefficients (length order) */ | ||
104 | const silk_float x[], /* I input signal, length: nb_subfr*(D+L_sub) */ | ||
105 | const silk_float minInvGain, /* I minimum inverse prediction gain */ | ||
106 | const opus_int subfr_length, /* I input signal subframe length (incl. D preceding samples) */ | ||
107 | const opus_int nb_subfr, /* I number of subframes stacked in x */ | ||
108 | const opus_int D /* I order */ | ||
109 | ); | ||
110 | |||
111 | /* multiply a vector by a constant */ | ||
112 | void silk_scale_vector_FLP( | ||
113 | silk_float *data1, | ||
114 | silk_float gain, | ||
115 | opus_int dataSize | ||
116 | ); | ||
117 | |||
118 | /* copy and multiply a vector by a constant */ | ||
119 | void silk_scale_copy_vector_FLP( | ||
120 | silk_float *data_out, | ||
121 | const silk_float *data_in, | ||
122 | silk_float gain, | ||
123 | opus_int dataSize | ||
124 | ); | ||
125 | |||
126 | /* inner product of two silk_float arrays, with result as double */ | ||
127 | double silk_inner_product_FLP( | ||
128 | const silk_float *data1, | ||
129 | const silk_float *data2, | ||
130 | opus_int dataSize | ||
131 | ); | ||
132 | |||
133 | /* sum of squares of a silk_float array, with result as double */ | ||
134 | double silk_energy_FLP( | ||
135 | const silk_float *data, | ||
136 | opus_int dataSize | ||
137 | ); | ||
138 | |||
139 | /********************************************************************/ | ||
140 | /* MACROS */ | ||
141 | /********************************************************************/ | ||
142 | |||
143 | #define PI (3.1415926536f) | ||
144 | |||
145 | #define silk_min_float( a, b ) (((a) < (b)) ? (a) : (b)) | ||
146 | #define silk_max_float( a, b ) (((a) > (b)) ? (a) : (b)) | ||
147 | #define silk_abs_float( a ) ((silk_float)fabs(a)) | ||
148 | |||
149 | /* sigmoid function */ | ||
150 | static OPUS_INLINE silk_float silk_sigmoid( silk_float x ) | ||
151 | { | ||
152 | return (silk_float)(1.0 / (1.0 + exp(-x))); | ||
153 | } | ||
154 | |||
155 | /* floating-point to integer conversion (rounding) */ | ||
156 | static OPUS_INLINE opus_int32 silk_float2int( silk_float x ) | ||
157 | { | ||
158 | return (opus_int32)float2int( x ); | ||
159 | } | ||
160 | |||
161 | /* floating-point to integer conversion (rounding) */ | ||
162 | static OPUS_INLINE void silk_float2short_array( | ||
163 | opus_int16 *out, | ||
164 | const silk_float *in, | ||
165 | opus_int32 length | ||
166 | ) | ||
167 | { | ||
168 | opus_int32 k; | ||
169 | for( k = length - 1; k >= 0; k-- ) { | ||
170 | out[k] = silk_SAT16( (opus_int32)float2int( in[k] ) ); | ||
171 | } | ||
172 | } | ||
173 | |||
174 | /* integer to floating-point conversion */ | ||
175 | static OPUS_INLINE void silk_short2float_array( | ||
176 | silk_float *out, | ||
177 | const opus_int16 *in, | ||
178 | opus_int32 length | ||
179 | ) | ||
180 | { | ||
181 | opus_int32 k; | ||
182 | for( k = length - 1; k >= 0; k-- ) { | ||
183 | out[k] = (silk_float)in[k]; | ||
184 | } | ||
185 | } | ||
186 | |||
187 | /* using log2() helps the fixed-point conversion */ | ||
188 | static OPUS_INLINE silk_float silk_log2( double x ) | ||
189 | { | ||
190 | return ( silk_float )( 3.32192809488736 * log10( x ) ); | ||
191 | } | ||
192 | |||
193 | #ifdef __cplusplus | ||
194 | } | ||
195 | #endif | ||
196 | |||
197 | #endif /* SILK_SIGPROC_FLP_H */ | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/float/apply_sine_window_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/apply_sine_window_FLP.c new file mode 100644 index 0000000000..e49e717991 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/float/apply_sine_window_FLP.c | |||
@@ -0,0 +1,81 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main_FLP.h" | ||
33 | |||
34 | /* Apply sine window to signal vector */ | ||
35 | /* Window types: */ | ||
36 | /* 1 -> sine window from 0 to pi/2 */ | ||
37 | /* 2 -> sine window from pi/2 to pi */ | ||
38 | void silk_apply_sine_window_FLP( | ||
39 | silk_float px_win[], /* O Pointer to windowed signal */ | ||
40 | const silk_float px[], /* I Pointer to input signal */ | ||
41 | const opus_int win_type, /* I Selects a window type */ | ||
42 | const opus_int length /* I Window length, multiple of 4 */ | ||
43 | ) | ||
44 | { | ||
45 | opus_int k; | ||
46 | silk_float freq, c, S0, S1; | ||
47 | |||
48 | celt_assert( win_type == 1 || win_type == 2 ); | ||
49 | |||
50 | /* Length must be multiple of 4 */ | ||
51 | celt_assert( ( length & 3 ) == 0 ); | ||
52 | |||
53 | freq = PI / ( length + 1 ); | ||
54 | |||
55 | /* Approximation of 2 * cos(f) */ | ||
56 | c = 2.0f - freq * freq; | ||
57 | |||
58 | /* Initialize state */ | ||
59 | if( win_type < 2 ) { | ||
60 | /* Start from 0 */ | ||
61 | S0 = 0.0f; | ||
62 | /* Approximation of sin(f) */ | ||
63 | S1 = freq; | ||
64 | } else { | ||
65 | /* Start from 1 */ | ||
66 | S0 = 1.0f; | ||
67 | /* Approximation of cos(f) */ | ||
68 | S1 = 0.5f * c; | ||
69 | } | ||
70 | |||
71 | /* Uses the recursive equation: sin(n*f) = 2 * cos(f) * sin((n-1)*f) - sin((n-2)*f) */ | ||
72 | /* 4 samples at a time */ | ||
73 | for( k = 0; k < length; k += 4 ) { | ||
74 | px_win[ k + 0 ] = px[ k + 0 ] * 0.5f * ( S0 + S1 ); | ||
75 | px_win[ k + 1 ] = px[ k + 1 ] * S1; | ||
76 | S0 = c * S1 - S0; | ||
77 | px_win[ k + 2 ] = px[ k + 2 ] * 0.5f * ( S1 + S0 ); | ||
78 | px_win[ k + 3 ] = px[ k + 3 ] * S0; | ||
79 | S1 = c * S0 - S1; | ||
80 | } | ||
81 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/float/autocorrelation_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/autocorrelation_FLP.c new file mode 100644 index 0000000000..8b8a9e659a --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/float/autocorrelation_FLP.c | |||
@@ -0,0 +1,52 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "typedef.h" | ||
33 | #include "SigProc_FLP.h" | ||
34 | |||
35 | /* compute autocorrelation */ | ||
36 | void silk_autocorrelation_FLP( | ||
37 | silk_float *results, /* O result (length correlationCount) */ | ||
38 | const silk_float *inputData, /* I input data to correlate */ | ||
39 | opus_int inputDataSize, /* I length of input */ | ||
40 | opus_int correlationCount /* I number of correlation taps to compute */ | ||
41 | ) | ||
42 | { | ||
43 | opus_int i; | ||
44 | |||
45 | if( correlationCount > inputDataSize ) { | ||
46 | correlationCount = inputDataSize; | ||
47 | } | ||
48 | |||
49 | for( i = 0; i < correlationCount; i++ ) { | ||
50 | results[ i ] = (silk_float)silk_inner_product_FLP( inputData, inputData + i, inputDataSize - i ); | ||
51 | } | ||
52 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/float/burg_modified_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/burg_modified_FLP.c new file mode 100644 index 0000000000..756b76a35b --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/float/burg_modified_FLP.c | |||
@@ -0,0 +1,186 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "SigProc_FLP.h" | ||
33 | #include "tuning_parameters.h" | ||
34 | #include "define.h" | ||
35 | |||
36 | #define MAX_FRAME_SIZE 384 /* subfr_length * nb_subfr = ( 0.005 * 16000 + 16 ) * 4 = 384*/ | ||
37 | |||
38 | /* Compute reflection coefficients from input signal */ | ||
39 | silk_float silk_burg_modified_FLP( /* O returns residual energy */ | ||
40 | silk_float A[], /* O prediction coefficients (length order) */ | ||
41 | const silk_float x[], /* I input signal, length: nb_subfr*(D+L_sub) */ | ||
42 | const silk_float minInvGain, /* I minimum inverse prediction gain */ | ||
43 | const opus_int subfr_length, /* I input signal subframe length (incl. D preceding samples) */ | ||
44 | const opus_int nb_subfr, /* I number of subframes stacked in x */ | ||
45 | const opus_int D /* I order */ | ||
46 | ) | ||
47 | { | ||
48 | opus_int k, n, s, reached_max_gain; | ||
49 | double C0, invGain, num, nrg_f, nrg_b, rc, Atmp, tmp1, tmp2; | ||
50 | const silk_float *x_ptr; | ||
51 | double C_first_row[ SILK_MAX_ORDER_LPC ], C_last_row[ SILK_MAX_ORDER_LPC ]; | ||
52 | double CAf[ SILK_MAX_ORDER_LPC + 1 ], CAb[ SILK_MAX_ORDER_LPC + 1 ]; | ||
53 | double Af[ SILK_MAX_ORDER_LPC ]; | ||
54 | |||
55 | celt_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE ); | ||
56 | |||
57 | /* Compute autocorrelations, added over subframes */ | ||
58 | C0 = silk_energy_FLP( x, nb_subfr * subfr_length ); | ||
59 | silk_memset( C_first_row, 0, SILK_MAX_ORDER_LPC * sizeof( double ) ); | ||
60 | for( s = 0; s < nb_subfr; s++ ) { | ||
61 | x_ptr = x + s * subfr_length; | ||
62 | for( n = 1; n < D + 1; n++ ) { | ||
63 | C_first_row[ n - 1 ] += silk_inner_product_FLP( x_ptr, x_ptr + n, subfr_length - n ); | ||
64 | } | ||
65 | } | ||
66 | silk_memcpy( C_last_row, C_first_row, SILK_MAX_ORDER_LPC * sizeof( double ) ); | ||
67 | |||
68 | /* Initialize */ | ||
69 | CAb[ 0 ] = CAf[ 0 ] = C0 + FIND_LPC_COND_FAC * C0 + 1e-9f; | ||
70 | invGain = 1.0f; | ||
71 | reached_max_gain = 0; | ||
72 | for( n = 0; n < D; n++ ) { | ||
73 | /* Update first row of correlation matrix (without first element) */ | ||
74 | /* Update last row of correlation matrix (without last element, stored in reversed order) */ | ||
75 | /* Update C * Af */ | ||
76 | /* Update C * flipud(Af) (stored in reversed order) */ | ||
77 | for( s = 0; s < nb_subfr; s++ ) { | ||
78 | x_ptr = x + s * subfr_length; | ||
79 | tmp1 = x_ptr[ n ]; | ||
80 | tmp2 = x_ptr[ subfr_length - n - 1 ]; | ||
81 | for( k = 0; k < n; k++ ) { | ||
82 | C_first_row[ k ] -= x_ptr[ n ] * x_ptr[ n - k - 1 ]; | ||
83 | C_last_row[ k ] -= x_ptr[ subfr_length - n - 1 ] * x_ptr[ subfr_length - n + k ]; | ||
84 | Atmp = Af[ k ]; | ||
85 | tmp1 += x_ptr[ n - k - 1 ] * Atmp; | ||
86 | tmp2 += x_ptr[ subfr_length - n + k ] * Atmp; | ||
87 | } | ||
88 | for( k = 0; k <= n; k++ ) { | ||
89 | CAf[ k ] -= tmp1 * x_ptr[ n - k ]; | ||
90 | CAb[ k ] -= tmp2 * x_ptr[ subfr_length - n + k - 1 ]; | ||
91 | } | ||
92 | } | ||
93 | tmp1 = C_first_row[ n ]; | ||
94 | tmp2 = C_last_row[ n ]; | ||
95 | for( k = 0; k < n; k++ ) { | ||
96 | Atmp = Af[ k ]; | ||
97 | tmp1 += C_last_row[ n - k - 1 ] * Atmp; | ||
98 | tmp2 += C_first_row[ n - k - 1 ] * Atmp; | ||
99 | } | ||
100 | CAf[ n + 1 ] = tmp1; | ||
101 | CAb[ n + 1 ] = tmp2; | ||
102 | |||
103 | /* Calculate nominator and denominator for the next order reflection (parcor) coefficient */ | ||
104 | num = CAb[ n + 1 ]; | ||
105 | nrg_b = CAb[ 0 ]; | ||
106 | nrg_f = CAf[ 0 ]; | ||
107 | for( k = 0; k < n; k++ ) { | ||
108 | Atmp = Af[ k ]; | ||
109 | num += CAb[ n - k ] * Atmp; | ||
110 | nrg_b += CAb[ k + 1 ] * Atmp; | ||
111 | nrg_f += CAf[ k + 1 ] * Atmp; | ||
112 | } | ||
113 | silk_assert( nrg_f > 0.0 ); | ||
114 | silk_assert( nrg_b > 0.0 ); | ||
115 | |||
116 | /* Calculate the next order reflection (parcor) coefficient */ | ||
117 | rc = -2.0 * num / ( nrg_f + nrg_b ); | ||
118 | silk_assert( rc > -1.0 && rc < 1.0 ); | ||
119 | |||
120 | /* Update inverse prediction gain */ | ||
121 | tmp1 = invGain * ( 1.0 - rc * rc ); | ||
122 | if( tmp1 <= minInvGain ) { | ||
123 | /* Max prediction gain exceeded; set reflection coefficient such that max prediction gain is exactly hit */ | ||
124 | rc = sqrt( 1.0 - minInvGain / invGain ); | ||
125 | if( num > 0 ) { | ||
126 | /* Ensure adjusted reflection coefficients has the original sign */ | ||
127 | rc = -rc; | ||
128 | } | ||
129 | invGain = minInvGain; | ||
130 | reached_max_gain = 1; | ||
131 | } else { | ||
132 | invGain = tmp1; | ||
133 | } | ||
134 | |||
135 | /* Update the AR coefficients */ | ||
136 | for( k = 0; k < (n + 1) >> 1; k++ ) { | ||
137 | tmp1 = Af[ k ]; | ||
138 | tmp2 = Af[ n - k - 1 ]; | ||
139 | Af[ k ] = tmp1 + rc * tmp2; | ||
140 | Af[ n - k - 1 ] = tmp2 + rc * tmp1; | ||
141 | } | ||
142 | Af[ n ] = rc; | ||
143 | |||
144 | if( reached_max_gain ) { | ||
145 | /* Reached max prediction gain; set remaining coefficients to zero and exit loop */ | ||
146 | for( k = n + 1; k < D; k++ ) { | ||
147 | Af[ k ] = 0.0; | ||
148 | } | ||
149 | break; | ||
150 | } | ||
151 | |||
152 | /* Update C * Af and C * Ab */ | ||
153 | for( k = 0; k <= n + 1; k++ ) { | ||
154 | tmp1 = CAf[ k ]; | ||
155 | CAf[ k ] += rc * CAb[ n - k + 1 ]; | ||
156 | CAb[ n - k + 1 ] += rc * tmp1; | ||
157 | } | ||
158 | } | ||
159 | |||
160 | if( reached_max_gain ) { | ||
161 | /* Convert to silk_float */ | ||
162 | for( k = 0; k < D; k++ ) { | ||
163 | A[ k ] = (silk_float)( -Af[ k ] ); | ||
164 | } | ||
165 | /* Subtract energy of preceding samples from C0 */ | ||
166 | for( s = 0; s < nb_subfr; s++ ) { | ||
167 | C0 -= silk_energy_FLP( x + s * subfr_length, D ); | ||
168 | } | ||
169 | /* Approximate residual energy */ | ||
170 | nrg_f = C0 * invGain; | ||
171 | } else { | ||
172 | /* Compute residual energy and store coefficients as silk_float */ | ||
173 | nrg_f = CAf[ 0 ]; | ||
174 | tmp1 = 1.0; | ||
175 | for( k = 0; k < D; k++ ) { | ||
176 | Atmp = Af[ k ]; | ||
177 | nrg_f += CAf[ k + 1 ] * Atmp; | ||
178 | tmp1 += Atmp * Atmp; | ||
179 | A[ k ] = (silk_float)(-Atmp); | ||
180 | } | ||
181 | nrg_f -= FIND_LPC_COND_FAC * C0 * tmp1; | ||
182 | } | ||
183 | |||
184 | /* Return residual energy */ | ||
185 | return (silk_float)nrg_f; | ||
186 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/float/bwexpander_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/bwexpander_FLP.c new file mode 100644 index 0000000000..d55a4d79ab --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/float/bwexpander_FLP.c | |||
@@ -0,0 +1,49 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "SigProc_FLP.h" | ||
33 | |||
34 | /* Chirp (bw expand) LP AR filter */ | ||
35 | void silk_bwexpander_FLP( | ||
36 | silk_float *ar, /* I/O AR filter to be expanded (without leading 1) */ | ||
37 | const opus_int d, /* I length of ar */ | ||
38 | const silk_float chirp /* I chirp factor (typically in range (0..1) ) */ | ||
39 | ) | ||
40 | { | ||
41 | opus_int i; | ||
42 | silk_float cfac = chirp; | ||
43 | |||
44 | for( i = 0; i < d - 1; i++ ) { | ||
45 | ar[ i ] *= cfac; | ||
46 | cfac *= chirp; | ||
47 | } | ||
48 | ar[ d - 1 ] *= cfac; | ||
49 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/float/corrMatrix_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/corrMatrix_FLP.c new file mode 100644 index 0000000000..eae6a1cfca --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/float/corrMatrix_FLP.c | |||
@@ -0,0 +1,93 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | /********************************************************************** | ||
33 | * Correlation matrix computations for LS estimate. | ||
34 | **********************************************************************/ | ||
35 | |||
36 | #include "main_FLP.h" | ||
37 | |||
38 | /* Calculates correlation vector X'*t */ | ||
39 | void silk_corrVector_FLP( | ||
40 | const silk_float *x, /* I x vector [L+order-1] used to create X */ | ||
41 | const silk_float *t, /* I Target vector [L] */ | ||
42 | const opus_int L, /* I Length of vecors */ | ||
43 | const opus_int Order, /* I Max lag for correlation */ | ||
44 | silk_float *Xt /* O X'*t correlation vector [order] */ | ||
45 | ) | ||
46 | { | ||
47 | opus_int lag; | ||
48 | const silk_float *ptr1; | ||
49 | |||
50 | ptr1 = &x[ Order - 1 ]; /* Points to first sample of column 0 of X: X[:,0] */ | ||
51 | for( lag = 0; lag < Order; lag++ ) { | ||
52 | /* Calculate X[:,lag]'*t */ | ||
53 | Xt[ lag ] = (silk_float)silk_inner_product_FLP( ptr1, t, L ); | ||
54 | ptr1--; /* Next column of X */ | ||
55 | } | ||
56 | } | ||
57 | |||
58 | /* Calculates correlation matrix X'*X */ | ||
59 | void silk_corrMatrix_FLP( | ||
60 | const silk_float *x, /* I x vector [ L+order-1 ] used to create X */ | ||
61 | const opus_int L, /* I Length of vectors */ | ||
62 | const opus_int Order, /* I Max lag for correlation */ | ||
63 | silk_float *XX /* O X'*X correlation matrix [order x order] */ | ||
64 | ) | ||
65 | { | ||
66 | opus_int j, lag; | ||
67 | double energy; | ||
68 | const silk_float *ptr1, *ptr2; | ||
69 | |||
70 | ptr1 = &x[ Order - 1 ]; /* First sample of column 0 of X */ | ||
71 | energy = silk_energy_FLP( ptr1, L ); /* X[:,0]'*X[:,0] */ | ||
72 | matrix_ptr( XX, 0, 0, Order ) = ( silk_float )energy; | ||
73 | for( j = 1; j < Order; j++ ) { | ||
74 | /* Calculate X[:,j]'*X[:,j] */ | ||
75 | energy += ptr1[ -j ] * ptr1[ -j ] - ptr1[ L - j ] * ptr1[ L - j ]; | ||
76 | matrix_ptr( XX, j, j, Order ) = ( silk_float )energy; | ||
77 | } | ||
78 | |||
79 | ptr2 = &x[ Order - 2 ]; /* First sample of column 1 of X */ | ||
80 | for( lag = 1; lag < Order; lag++ ) { | ||
81 | /* Calculate X[:,0]'*X[:,lag] */ | ||
82 | energy = silk_inner_product_FLP( ptr1, ptr2, L ); | ||
83 | matrix_ptr( XX, lag, 0, Order ) = ( silk_float )energy; | ||
84 | matrix_ptr( XX, 0, lag, Order ) = ( silk_float )energy; | ||
85 | /* Calculate X[:,j]'*X[:,j + lag] */ | ||
86 | for( j = 1; j < ( Order - lag ); j++ ) { | ||
87 | energy += ptr1[ -j ] * ptr2[ -j ] - ptr1[ L - j ] * ptr2[ L - j ]; | ||
88 | matrix_ptr( XX, lag + j, j, Order ) = ( silk_float )energy; | ||
89 | matrix_ptr( XX, j, lag + j, Order ) = ( silk_float )energy; | ||
90 | } | ||
91 | ptr2--; /* Next column of X */ | ||
92 | } | ||
93 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/float/encode_frame_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/encode_frame_FLP.c new file mode 100644 index 0000000000..b029c3f5ca --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/float/encode_frame_FLP.c | |||
@@ -0,0 +1,435 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include <stdlib.h> | ||
33 | #include "main_FLP.h" | ||
34 | #include "tuning_parameters.h" | ||
35 | |||
36 | /* Low Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode with lower bitrate */ | ||
37 | static OPUS_INLINE void silk_LBRR_encode_FLP( | ||
38 | silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ | ||
39 | silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ | ||
40 | const silk_float xfw[], /* I Input signal */ | ||
41 | opus_int condCoding /* I The type of conditional coding used so far for this frame */ | ||
42 | ); | ||
43 | |||
44 | void silk_encode_do_VAD_FLP( | ||
45 | silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ | ||
46 | opus_int activity /* I Decision of Opus voice activity detector */ | ||
47 | ) | ||
48 | { | ||
49 | const opus_int activity_threshold = SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ); | ||
50 | |||
51 | /****************************/ | ||
52 | /* Voice Activity Detection */ | ||
53 | /****************************/ | ||
54 | silk_VAD_GetSA_Q8( &psEnc->sCmn, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.arch ); | ||
55 | /* If Opus VAD is inactive and Silk VAD is active: lower Silk VAD to just under the threshold */ | ||
56 | if( activity == VAD_NO_ACTIVITY && psEnc->sCmn.speech_activity_Q8 >= activity_threshold ) { | ||
57 | psEnc->sCmn.speech_activity_Q8 = activity_threshold - 1; | ||
58 | } | ||
59 | |||
60 | /**************************************************/ | ||
61 | /* Convert speech activity into VAD and DTX flags */ | ||
62 | /**************************************************/ | ||
63 | if( psEnc->sCmn.speech_activity_Q8 < activity_threshold ) { | ||
64 | psEnc->sCmn.indices.signalType = TYPE_NO_VOICE_ACTIVITY; | ||
65 | psEnc->sCmn.noSpeechCounter++; | ||
66 | if( psEnc->sCmn.noSpeechCounter <= NB_SPEECH_FRAMES_BEFORE_DTX ) { | ||
67 | psEnc->sCmn.inDTX = 0; | ||
68 | } else if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NB_SPEECH_FRAMES_BEFORE_DTX ) { | ||
69 | psEnc->sCmn.noSpeechCounter = NB_SPEECH_FRAMES_BEFORE_DTX; | ||
70 | psEnc->sCmn.inDTX = 0; | ||
71 | } | ||
72 | psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 0; | ||
73 | } else { | ||
74 | psEnc->sCmn.noSpeechCounter = 0; | ||
75 | psEnc->sCmn.inDTX = 0; | ||
76 | psEnc->sCmn.indices.signalType = TYPE_UNVOICED; | ||
77 | psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 1; | ||
78 | } | ||
79 | } | ||
80 | |||
81 | /****************/ | ||
82 | /* Encode frame */ | ||
83 | /****************/ | ||
84 | opus_int silk_encode_frame_FLP( | ||
85 | silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ | ||
86 | opus_int32 *pnBytesOut, /* O Number of payload bytes; */ | ||
87 | ec_enc *psRangeEnc, /* I/O compressor data structure */ | ||
88 | opus_int condCoding, /* I The type of conditional coding to use */ | ||
89 | opus_int maxBits, /* I If > 0: maximum number of output bits */ | ||
90 | opus_int useCBR /* I Flag to force constant-bitrate operation */ | ||
91 | ) | ||
92 | { | ||
93 | silk_encoder_control_FLP sEncCtrl; | ||
94 | opus_int i, iter, maxIter, found_upper, found_lower, ret = 0; | ||
95 | silk_float *x_frame, *res_pitch_frame; | ||
96 | silk_float res_pitch[ 2 * MAX_FRAME_LENGTH + LA_PITCH_MAX ]; | ||
97 | ec_enc sRangeEnc_copy, sRangeEnc_copy2; | ||
98 | silk_nsq_state sNSQ_copy, sNSQ_copy2; | ||
99 | opus_int32 seed_copy, nBits, nBits_lower, nBits_upper, gainMult_lower, gainMult_upper; | ||
100 | opus_int32 gainsID, gainsID_lower, gainsID_upper; | ||
101 | opus_int16 gainMult_Q8; | ||
102 | opus_int16 ec_prevLagIndex_copy; | ||
103 | opus_int ec_prevSignalType_copy; | ||
104 | opus_int8 LastGainIndex_copy2; | ||
105 | opus_int32 pGains_Q16[ MAX_NB_SUBFR ]; | ||
106 | opus_uint8 ec_buf_copy[ 1275 ]; | ||
107 | opus_int gain_lock[ MAX_NB_SUBFR ] = {0}; | ||
108 | opus_int16 best_gain_mult[ MAX_NB_SUBFR ]; | ||
109 | opus_int best_sum[ MAX_NB_SUBFR ]; | ||
110 | |||
111 | /* This is totally unnecessary but many compilers (including gcc) are too dumb to realise it */ | ||
112 | LastGainIndex_copy2 = nBits_lower = nBits_upper = gainMult_lower = gainMult_upper = 0; | ||
113 | |||
114 | psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3; | ||
115 | |||
116 | /**************************************************************/ | ||
117 | /* Set up Input Pointers, and insert frame in input buffer */ | ||
118 | /**************************************************************/ | ||
119 | /* pointers aligned with start of frame to encode */ | ||
120 | x_frame = psEnc->x_buf + psEnc->sCmn.ltp_mem_length; /* start of frame to encode */ | ||
121 | res_pitch_frame = res_pitch + psEnc->sCmn.ltp_mem_length; /* start of pitch LPC residual frame */ | ||
122 | |||
123 | /***************************************/ | ||
124 | /* Ensure smooth bandwidth transitions */ | ||
125 | /***************************************/ | ||
126 | silk_LP_variable_cutoff( &psEnc->sCmn.sLP, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length ); | ||
127 | |||
128 | /*******************************************/ | ||
129 | /* Copy new frame to front of input buffer */ | ||
130 | /*******************************************/ | ||
131 | silk_short2float_array( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length ); | ||
132 | |||
133 | /* Add tiny signal to avoid high CPU load from denormalized floating point numbers */ | ||
134 | for( i = 0; i < 8; i++ ) { | ||
135 | x_frame[ LA_SHAPE_MS * psEnc->sCmn.fs_kHz + i * ( psEnc->sCmn.frame_length >> 3 ) ] += ( 1 - ( i & 2 ) ) * 1e-6f; | ||
136 | } | ||
137 | |||
138 | if( !psEnc->sCmn.prefillFlag ) { | ||
139 | /*****************************************/ | ||
140 | /* Find pitch lags, initial LPC analysis */ | ||
141 | /*****************************************/ | ||
142 | silk_find_pitch_lags_FLP( psEnc, &sEncCtrl, res_pitch, x_frame, psEnc->sCmn.arch ); | ||
143 | |||
144 | /************************/ | ||
145 | /* Noise shape analysis */ | ||
146 | /************************/ | ||
147 | silk_noise_shape_analysis_FLP( psEnc, &sEncCtrl, res_pitch_frame, x_frame ); | ||
148 | |||
149 | /***************************************************/ | ||
150 | /* Find linear prediction coefficients (LPC + LTP) */ | ||
151 | /***************************************************/ | ||
152 | silk_find_pred_coefs_FLP( psEnc, &sEncCtrl, res_pitch_frame, x_frame, condCoding ); | ||
153 | |||
154 | /****************************************/ | ||
155 | /* Process gains */ | ||
156 | /****************************************/ | ||
157 | silk_process_gains_FLP( psEnc, &sEncCtrl, condCoding ); | ||
158 | |||
159 | /****************************************/ | ||
160 | /* Low Bitrate Redundant Encoding */ | ||
161 | /****************************************/ | ||
162 | silk_LBRR_encode_FLP( psEnc, &sEncCtrl, x_frame, condCoding ); | ||
163 | |||
164 | /* Loop over quantizer and entroy coding to control bitrate */ | ||
165 | maxIter = 6; | ||
166 | gainMult_Q8 = SILK_FIX_CONST( 1, 8 ); | ||
167 | found_lower = 0; | ||
168 | found_upper = 0; | ||
169 | gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr ); | ||
170 | gainsID_lower = -1; | ||
171 | gainsID_upper = -1; | ||
172 | /* Copy part of the input state */ | ||
173 | silk_memcpy( &sRangeEnc_copy, psRangeEnc, sizeof( ec_enc ) ); | ||
174 | silk_memcpy( &sNSQ_copy, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); | ||
175 | seed_copy = psEnc->sCmn.indices.Seed; | ||
176 | ec_prevLagIndex_copy = psEnc->sCmn.ec_prevLagIndex; | ||
177 | ec_prevSignalType_copy = psEnc->sCmn.ec_prevSignalType; | ||
178 | for( iter = 0; ; iter++ ) { | ||
179 | if( gainsID == gainsID_lower ) { | ||
180 | nBits = nBits_lower; | ||
181 | } else if( gainsID == gainsID_upper ) { | ||
182 | nBits = nBits_upper; | ||
183 | } else { | ||
184 | /* Restore part of the input state */ | ||
185 | if( iter > 0 ) { | ||
186 | silk_memcpy( psRangeEnc, &sRangeEnc_copy, sizeof( ec_enc ) ); | ||
187 | silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy, sizeof( silk_nsq_state ) ); | ||
188 | psEnc->sCmn.indices.Seed = seed_copy; | ||
189 | psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy; | ||
190 | psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy; | ||
191 | } | ||
192 | |||
193 | /*****************************************/ | ||
194 | /* Noise shaping quantization */ | ||
195 | /*****************************************/ | ||
196 | silk_NSQ_wrapper_FLP( psEnc, &sEncCtrl, &psEnc->sCmn.indices, &psEnc->sCmn.sNSQ, psEnc->sCmn.pulses, x_frame ); | ||
197 | |||
198 | if ( iter == maxIter && !found_lower ) { | ||
199 | silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) ); | ||
200 | } | ||
201 | |||
202 | /****************************************/ | ||
203 | /* Encode Parameters */ | ||
204 | /****************************************/ | ||
205 | silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding ); | ||
206 | |||
207 | /****************************************/ | ||
208 | /* Encode Excitation Signal */ | ||
209 | /****************************************/ | ||
210 | silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType, | ||
211 | psEnc->sCmn.pulses, psEnc->sCmn.frame_length ); | ||
212 | |||
213 | nBits = ec_tell( psRangeEnc ); | ||
214 | |||
215 | /* If we still bust after the last iteration, do some damage control. */ | ||
216 | if ( iter == maxIter && !found_lower && nBits > maxBits ) { | ||
217 | silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) ); | ||
218 | |||
219 | /* Keep gains the same as the last frame. */ | ||
220 | psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev; | ||
221 | for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { | ||
222 | psEnc->sCmn.indices.GainsIndices[ i ] = 4; | ||
223 | } | ||
224 | if (condCoding != CODE_CONDITIONALLY) { | ||
225 | psEnc->sCmn.indices.GainsIndices[ 0 ] = sEncCtrl.lastGainIndexPrev; | ||
226 | } | ||
227 | psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy; | ||
228 | psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy; | ||
229 | /* Clear all pulses. */ | ||
230 | for ( i = 0; i < psEnc->sCmn.frame_length; i++ ) { | ||
231 | psEnc->sCmn.pulses[ i ] = 0; | ||
232 | } | ||
233 | |||
234 | silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding ); | ||
235 | |||
236 | silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType, | ||
237 | psEnc->sCmn.pulses, psEnc->sCmn.frame_length ); | ||
238 | |||
239 | nBits = ec_tell( psRangeEnc ); | ||
240 | } | ||
241 | |||
242 | if( useCBR == 0 && iter == 0 && nBits <= maxBits ) { | ||
243 | break; | ||
244 | } | ||
245 | } | ||
246 | |||
247 | if( iter == maxIter ) { | ||
248 | if( found_lower && ( gainsID == gainsID_lower || nBits > maxBits ) ) { | ||
249 | /* Restore output state from earlier iteration that did meet the bitrate budget */ | ||
250 | silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) ); | ||
251 | celt_assert( sRangeEnc_copy2.offs <= 1275 ); | ||
252 | silk_memcpy( psRangeEnc->buf, ec_buf_copy, sRangeEnc_copy2.offs ); | ||
253 | silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy2, sizeof( silk_nsq_state ) ); | ||
254 | psEnc->sShape.LastGainIndex = LastGainIndex_copy2; | ||
255 | } | ||
256 | break; | ||
257 | } | ||
258 | |||
259 | if( nBits > maxBits ) { | ||
260 | if( found_lower == 0 && iter >= 2 ) { | ||
261 | /* Adjust the quantizer's rate/distortion tradeoff and discard previous "upper" results */ | ||
262 | sEncCtrl.Lambda = silk_max_float(sEncCtrl.Lambda*1.5f, 1.5f); | ||
263 | /* Reducing dithering can help us hit the target. */ | ||
264 | psEnc->sCmn.indices.quantOffsetType = 0; | ||
265 | found_upper = 0; | ||
266 | gainsID_upper = -1; | ||
267 | } else { | ||
268 | found_upper = 1; | ||
269 | nBits_upper = nBits; | ||
270 | gainMult_upper = gainMult_Q8; | ||
271 | gainsID_upper = gainsID; | ||
272 | } | ||
273 | } else if( nBits < maxBits - 5 ) { | ||
274 | found_lower = 1; | ||
275 | nBits_lower = nBits; | ||
276 | gainMult_lower = gainMult_Q8; | ||
277 | if( gainsID != gainsID_lower ) { | ||
278 | gainsID_lower = gainsID; | ||
279 | /* Copy part of the output state */ | ||
280 | silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) ); | ||
281 | celt_assert( psRangeEnc->offs <= 1275 ); | ||
282 | silk_memcpy( ec_buf_copy, psRangeEnc->buf, psRangeEnc->offs ); | ||
283 | silk_memcpy( &sNSQ_copy2, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); | ||
284 | LastGainIndex_copy2 = psEnc->sShape.LastGainIndex; | ||
285 | } | ||
286 | } else { | ||
287 | /* Within 5 bits of budget: close enough */ | ||
288 | break; | ||
289 | } | ||
290 | |||
291 | if ( !found_lower && nBits > maxBits ) { | ||
292 | int j; | ||
293 | for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { | ||
294 | int sum=0; | ||
295 | for ( j = i*psEnc->sCmn.subfr_length; j < (i+1)*psEnc->sCmn.subfr_length; j++ ) { | ||
296 | sum += abs( psEnc->sCmn.pulses[j] ); | ||
297 | } | ||
298 | if ( iter == 0 || (sum < best_sum[i] && !gain_lock[i]) ) { | ||
299 | best_sum[i] = sum; | ||
300 | best_gain_mult[i] = gainMult_Q8; | ||
301 | } else { | ||
302 | gain_lock[i] = 1; | ||
303 | } | ||
304 | } | ||
305 | } | ||
306 | if( ( found_lower & found_upper ) == 0 ) { | ||
307 | /* Adjust gain according to high-rate rate/distortion curve */ | ||
308 | if( nBits > maxBits ) { | ||
309 | if (gainMult_Q8 < 16384) { | ||
310 | gainMult_Q8 *= 2; | ||
311 | } else { | ||
312 | gainMult_Q8 = 32767; | ||
313 | } | ||
314 | } else { | ||
315 | opus_int32 gain_factor_Q16; | ||
316 | gain_factor_Q16 = silk_log2lin( silk_LSHIFT( nBits - maxBits, 7 ) / psEnc->sCmn.frame_length + SILK_FIX_CONST( 16, 7 ) ); | ||
317 | gainMult_Q8 = silk_SMULWB( gain_factor_Q16, gainMult_Q8 ); | ||
318 | } | ||
319 | } else { | ||
320 | /* Adjust gain by interpolating */ | ||
321 | gainMult_Q8 = gainMult_lower + ( ( gainMult_upper - gainMult_lower ) * ( maxBits - nBits_lower ) ) / ( nBits_upper - nBits_lower ); | ||
322 | /* New gain multplier must be between 25% and 75% of old range (note that gainMult_upper < gainMult_lower) */ | ||
323 | if( gainMult_Q8 > silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ) ) { | ||
324 | gainMult_Q8 = silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ); | ||
325 | } else | ||
326 | if( gainMult_Q8 < silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ) ) { | ||
327 | gainMult_Q8 = silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ); | ||
328 | } | ||
329 | } | ||
330 | |||
331 | for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { | ||
332 | opus_int16 tmp; | ||
333 | if ( gain_lock[i] ) { | ||
334 | tmp = best_gain_mult[i]; | ||
335 | } else { | ||
336 | tmp = gainMult_Q8; | ||
337 | } | ||
338 | pGains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], tmp ), 8 ); | ||
339 | } | ||
340 | |||
341 | /* Quantize gains */ | ||
342 | psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev; | ||
343 | silk_gains_quant( psEnc->sCmn.indices.GainsIndices, pGains_Q16, | ||
344 | &psEnc->sShape.LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr ); | ||
345 | |||
346 | /* Unique identifier of gains vector */ | ||
347 | gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr ); | ||
348 | |||
349 | /* Overwrite unquantized gains with quantized gains and convert back to Q0 from Q16 */ | ||
350 | for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { | ||
351 | sEncCtrl.Gains[ i ] = pGains_Q16[ i ] / 65536.0f; | ||
352 | } | ||
353 | } | ||
354 | } | ||
355 | |||
356 | /* Update input buffer */ | ||
357 | silk_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ], | ||
358 | ( psEnc->sCmn.ltp_mem_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( silk_float ) ); | ||
359 | |||
360 | /* Exit without entropy coding */ | ||
361 | if( psEnc->sCmn.prefillFlag ) { | ||
362 | /* No payload */ | ||
363 | *pnBytesOut = 0; | ||
364 | return ret; | ||
365 | } | ||
366 | |||
367 | /* Parameters needed for next frame */ | ||
368 | psEnc->sCmn.prevLag = sEncCtrl.pitchL[ psEnc->sCmn.nb_subfr - 1 ]; | ||
369 | psEnc->sCmn.prevSignalType = psEnc->sCmn.indices.signalType; | ||
370 | |||
371 | /****************************************/ | ||
372 | /* Finalize payload */ | ||
373 | /****************************************/ | ||
374 | psEnc->sCmn.first_frame_after_reset = 0; | ||
375 | /* Payload size */ | ||
376 | *pnBytesOut = silk_RSHIFT( ec_tell( psRangeEnc ) + 7, 3 ); | ||
377 | |||
378 | return ret; | ||
379 | } | ||
380 | |||
381 | /* Low-Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode excitation at lower bitrate */ | ||
382 | static OPUS_INLINE void silk_LBRR_encode_FLP( | ||
383 | silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ | ||
384 | silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ | ||
385 | const silk_float xfw[], /* I Input signal */ | ||
386 | opus_int condCoding /* I The type of conditional coding used so far for this frame */ | ||
387 | ) | ||
388 | { | ||
389 | opus_int k; | ||
390 | opus_int32 Gains_Q16[ MAX_NB_SUBFR ]; | ||
391 | silk_float TempGains[ MAX_NB_SUBFR ]; | ||
392 | SideInfoIndices *psIndices_LBRR = &psEnc->sCmn.indices_LBRR[ psEnc->sCmn.nFramesEncoded ]; | ||
393 | silk_nsq_state sNSQ_LBRR; | ||
394 | |||
395 | /*******************************************/ | ||
396 | /* Control use of inband LBRR */ | ||
397 | /*******************************************/ | ||
398 | if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.speech_activity_Q8 > SILK_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) ) { | ||
399 | psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded ] = 1; | ||
400 | |||
401 | /* Copy noise shaping quantizer state and quantization indices from regular encoding */ | ||
402 | silk_memcpy( &sNSQ_LBRR, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); | ||
403 | silk_memcpy( psIndices_LBRR, &psEnc->sCmn.indices, sizeof( SideInfoIndices ) ); | ||
404 | |||
405 | /* Save original gains */ | ||
406 | silk_memcpy( TempGains, psEncCtrl->Gains, psEnc->sCmn.nb_subfr * sizeof( silk_float ) ); | ||
407 | |||
408 | if( psEnc->sCmn.nFramesEncoded == 0 || psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded - 1 ] == 0 ) { | ||
409 | /* First frame in packet or previous frame not LBRR coded */ | ||
410 | psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex; | ||
411 | |||
412 | /* Increase Gains to get target LBRR rate */ | ||
413 | psIndices_LBRR->GainsIndices[ 0 ] += psEnc->sCmn.LBRR_GainIncreases; | ||
414 | psIndices_LBRR->GainsIndices[ 0 ] = silk_min_int( psIndices_LBRR->GainsIndices[ 0 ], N_LEVELS_QGAIN - 1 ); | ||
415 | } | ||
416 | |||
417 | /* Decode to get gains in sync with decoder */ | ||
418 | silk_gains_dequant( Gains_Q16, psIndices_LBRR->GainsIndices, | ||
419 | &psEnc->sCmn.LBRRprevLastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr ); | ||
420 | |||
421 | /* Overwrite unquantized gains with quantized gains and convert back to Q0 from Q16 */ | ||
422 | for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { | ||
423 | psEncCtrl->Gains[ k ] = Gains_Q16[ k ] * ( 1.0f / 65536.0f ); | ||
424 | } | ||
425 | |||
426 | /*****************************************/ | ||
427 | /* Noise shaping quantization */ | ||
428 | /*****************************************/ | ||
429 | silk_NSQ_wrapper_FLP( psEnc, psEncCtrl, psIndices_LBRR, &sNSQ_LBRR, | ||
430 | psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], xfw ); | ||
431 | |||
432 | /* Restore original gains */ | ||
433 | silk_memcpy( psEncCtrl->Gains, TempGains, psEnc->sCmn.nb_subfr * sizeof( silk_float ) ); | ||
434 | } | ||
435 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/float/energy_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/energy_FLP.c new file mode 100644 index 0000000000..7bc7173c9c --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/float/energy_FLP.c | |||
@@ -0,0 +1,59 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "SigProc_FLP.h" | ||
33 | |||
34 | /* sum of squares of a silk_float array, with result as double */ | ||
35 | double silk_energy_FLP( | ||
36 | const silk_float *data, | ||
37 | opus_int dataSize | ||
38 | ) | ||
39 | { | ||
40 | opus_int i; | ||
41 | double result; | ||
42 | |||
43 | /* 4x unrolled loop */ | ||
44 | result = 0.0; | ||
45 | for( i = 0; i < dataSize - 3; i += 4 ) { | ||
46 | result += data[ i + 0 ] * (double)data[ i + 0 ] + | ||
47 | data[ i + 1 ] * (double)data[ i + 1 ] + | ||
48 | data[ i + 2 ] * (double)data[ i + 2 ] + | ||
49 | data[ i + 3 ] * (double)data[ i + 3 ]; | ||
50 | } | ||
51 | |||
52 | /* add any remaining products */ | ||
53 | for( ; i < dataSize; i++ ) { | ||
54 | result += data[ i ] * (double)data[ i ]; | ||
55 | } | ||
56 | |||
57 | silk_assert( result >= 0.0 ); | ||
58 | return result; | ||
59 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/float/find_LPC_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/find_LPC_FLP.c new file mode 100644 index 0000000000..fa3ffe7f8b --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/float/find_LPC_FLP.c | |||
@@ -0,0 +1,104 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "define.h" | ||
33 | #include "main_FLP.h" | ||
34 | #include "tuning_parameters.h" | ||
35 | |||
36 | /* LPC analysis */ | ||
37 | void silk_find_LPC_FLP( | ||
38 | silk_encoder_state *psEncC, /* I/O Encoder state */ | ||
39 | opus_int16 NLSF_Q15[], /* O NLSFs */ | ||
40 | const silk_float x[], /* I Input signal */ | ||
41 | const silk_float minInvGain /* I Inverse of max prediction gain */ | ||
42 | ) | ||
43 | { | ||
44 | opus_int k, subfr_length; | ||
45 | silk_float a[ MAX_LPC_ORDER ]; | ||
46 | |||
47 | /* Used only for NLSF interpolation */ | ||
48 | silk_float res_nrg, res_nrg_2nd, res_nrg_interp; | ||
49 | opus_int16 NLSF0_Q15[ MAX_LPC_ORDER ]; | ||
50 | silk_float a_tmp[ MAX_LPC_ORDER ]; | ||
51 | silk_float LPC_res[ MAX_FRAME_LENGTH + MAX_NB_SUBFR * MAX_LPC_ORDER ]; | ||
52 | |||
53 | subfr_length = psEncC->subfr_length + psEncC->predictLPCOrder; | ||
54 | |||
55 | /* Default: No interpolation */ | ||
56 | psEncC->indices.NLSFInterpCoef_Q2 = 4; | ||
57 | |||
58 | /* Burg AR analysis for the full frame */ | ||
59 | res_nrg = silk_burg_modified_FLP( a, x, minInvGain, subfr_length, psEncC->nb_subfr, psEncC->predictLPCOrder ); | ||
60 | |||
61 | if( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) { | ||
62 | /* Optimal solution for last 10 ms; subtract residual energy here, as that's easier than */ | ||
63 | /* adding it to the residual energy of the first 10 ms in each iteration of the search below */ | ||
64 | res_nrg -= silk_burg_modified_FLP( a_tmp, x + ( MAX_NB_SUBFR / 2 ) * subfr_length, minInvGain, subfr_length, MAX_NB_SUBFR / 2, psEncC->predictLPCOrder ); | ||
65 | |||
66 | /* Convert to NLSFs */ | ||
67 | silk_A2NLSF_FLP( NLSF_Q15, a_tmp, psEncC->predictLPCOrder ); | ||
68 | |||
69 | /* Search over interpolation indices to find the one with lowest residual energy */ | ||
70 | res_nrg_2nd = silk_float_MAX; | ||
71 | for( k = 3; k >= 0; k-- ) { | ||
72 | /* Interpolate NLSFs for first half */ | ||
73 | silk_interpolate( NLSF0_Q15, psEncC->prev_NLSFq_Q15, NLSF_Q15, k, psEncC->predictLPCOrder ); | ||
74 | |||
75 | /* Convert to LPC for residual energy evaluation */ | ||
76 | silk_NLSF2A_FLP( a_tmp, NLSF0_Q15, psEncC->predictLPCOrder, psEncC->arch ); | ||
77 | |||
78 | /* Calculate residual energy with LSF interpolation */ | ||
79 | silk_LPC_analysis_filter_FLP( LPC_res, a_tmp, x, 2 * subfr_length, psEncC->predictLPCOrder ); | ||
80 | res_nrg_interp = (silk_float)( | ||
81 | silk_energy_FLP( LPC_res + psEncC->predictLPCOrder, subfr_length - psEncC->predictLPCOrder ) + | ||
82 | silk_energy_FLP( LPC_res + psEncC->predictLPCOrder + subfr_length, subfr_length - psEncC->predictLPCOrder ) ); | ||
83 | |||
84 | /* Determine whether current interpolated NLSFs are best so far */ | ||
85 | if( res_nrg_interp < res_nrg ) { | ||
86 | /* Interpolation has lower residual energy */ | ||
87 | res_nrg = res_nrg_interp; | ||
88 | psEncC->indices.NLSFInterpCoef_Q2 = (opus_int8)k; | ||
89 | } else if( res_nrg_interp > res_nrg_2nd ) { | ||
90 | /* No reason to continue iterating - residual energies will continue to climb */ | ||
91 | break; | ||
92 | } | ||
93 | res_nrg_2nd = res_nrg_interp; | ||
94 | } | ||
95 | } | ||
96 | |||
97 | if( psEncC->indices.NLSFInterpCoef_Q2 == 4 ) { | ||
98 | /* NLSF interpolation is currently inactive, calculate NLSFs from full frame AR coefficients */ | ||
99 | silk_A2NLSF_FLP( NLSF_Q15, a, psEncC->predictLPCOrder ); | ||
100 | } | ||
101 | |||
102 | celt_assert( psEncC->indices.NLSFInterpCoef_Q2 == 4 || | ||
103 | ( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) ); | ||
104 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/float/find_LTP_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/find_LTP_FLP.c new file mode 100644 index 0000000000..f97064930e --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/float/find_LTP_FLP.c | |||
@@ -0,0 +1,64 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main_FLP.h" | ||
33 | #include "tuning_parameters.h" | ||
34 | |||
35 | void silk_find_LTP_FLP( | ||
36 | silk_float XX[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Weight for LTP quantization */ | ||
37 | silk_float xX[ MAX_NB_SUBFR * LTP_ORDER ], /* O Weight for LTP quantization */ | ||
38 | const silk_float r_ptr[], /* I LPC residual */ | ||
39 | const opus_int lag[ MAX_NB_SUBFR ], /* I LTP lags */ | ||
40 | const opus_int subfr_length, /* I Subframe length */ | ||
41 | const opus_int nb_subfr /* I number of subframes */ | ||
42 | ) | ||
43 | { | ||
44 | opus_int k; | ||
45 | silk_float *xX_ptr, *XX_ptr; | ||
46 | const silk_float *lag_ptr; | ||
47 | silk_float xx, temp; | ||
48 | |||
49 | xX_ptr = xX; | ||
50 | XX_ptr = XX; | ||
51 | for( k = 0; k < nb_subfr; k++ ) { | ||
52 | lag_ptr = r_ptr - ( lag[ k ] + LTP_ORDER / 2 ); | ||
53 | silk_corrMatrix_FLP( lag_ptr, subfr_length, LTP_ORDER, XX_ptr ); | ||
54 | silk_corrVector_FLP( lag_ptr, r_ptr, subfr_length, LTP_ORDER, xX_ptr ); | ||
55 | xx = ( silk_float )silk_energy_FLP( r_ptr, subfr_length + LTP_ORDER ); | ||
56 | temp = 1.0f / silk_max( xx, LTP_CORR_INV_MAX * 0.5f * ( XX_ptr[ 0 ] + XX_ptr[ 24 ] ) + 1.0f ); | ||
57 | silk_scale_vector_FLP( XX_ptr, temp, LTP_ORDER * LTP_ORDER ); | ||
58 | silk_scale_vector_FLP( xX_ptr, temp, LTP_ORDER ); | ||
59 | |||
60 | r_ptr += subfr_length; | ||
61 | XX_ptr += LTP_ORDER * LTP_ORDER; | ||
62 | xX_ptr += LTP_ORDER; | ||
63 | } | ||
64 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/float/find_pitch_lags_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/find_pitch_lags_FLP.c new file mode 100644 index 0000000000..dedbcd2836 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/float/find_pitch_lags_FLP.c | |||
@@ -0,0 +1,132 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include <stdlib.h> | ||
33 | #include "main_FLP.h" | ||
34 | #include "tuning_parameters.h" | ||
35 | |||
36 | void silk_find_pitch_lags_FLP( | ||
37 | silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ | ||
38 | silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ | ||
39 | silk_float res[], /* O Residual */ | ||
40 | const silk_float x[], /* I Speech signal */ | ||
41 | int arch /* I Run-time architecture */ | ||
42 | ) | ||
43 | { | ||
44 | opus_int buf_len; | ||
45 | silk_float thrhld, res_nrg; | ||
46 | const silk_float *x_buf_ptr, *x_buf; | ||
47 | silk_float auto_corr[ MAX_FIND_PITCH_LPC_ORDER + 1 ]; | ||
48 | silk_float A[ MAX_FIND_PITCH_LPC_ORDER ]; | ||
49 | silk_float refl_coef[ MAX_FIND_PITCH_LPC_ORDER ]; | ||
50 | silk_float Wsig[ FIND_PITCH_LPC_WIN_MAX ]; | ||
51 | silk_float *Wsig_ptr; | ||
52 | |||
53 | /******************************************/ | ||
54 | /* Set up buffer lengths etc based on Fs */ | ||
55 | /******************************************/ | ||
56 | buf_len = psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + psEnc->sCmn.ltp_mem_length; | ||
57 | |||
58 | /* Safety check */ | ||
59 | celt_assert( buf_len >= psEnc->sCmn.pitch_LPC_win_length ); | ||
60 | |||
61 | x_buf = x - psEnc->sCmn.ltp_mem_length; | ||
62 | |||
63 | /******************************************/ | ||
64 | /* Estimate LPC AR coeficients */ | ||
65 | /******************************************/ | ||
66 | |||
67 | /* Calculate windowed signal */ | ||
68 | |||
69 | /* First LA_LTP samples */ | ||
70 | x_buf_ptr = x_buf + buf_len - psEnc->sCmn.pitch_LPC_win_length; | ||
71 | Wsig_ptr = Wsig; | ||
72 | silk_apply_sine_window_FLP( Wsig_ptr, x_buf_ptr, 1, psEnc->sCmn.la_pitch ); | ||
73 | |||
74 | /* Middle non-windowed samples */ | ||
75 | Wsig_ptr += psEnc->sCmn.la_pitch; | ||
76 | x_buf_ptr += psEnc->sCmn.la_pitch; | ||
77 | silk_memcpy( Wsig_ptr, x_buf_ptr, ( psEnc->sCmn.pitch_LPC_win_length - ( psEnc->sCmn.la_pitch << 1 ) ) * sizeof( silk_float ) ); | ||
78 | |||
79 | /* Last LA_LTP samples */ | ||
80 | Wsig_ptr += psEnc->sCmn.pitch_LPC_win_length - ( psEnc->sCmn.la_pitch << 1 ); | ||
81 | x_buf_ptr += psEnc->sCmn.pitch_LPC_win_length - ( psEnc->sCmn.la_pitch << 1 ); | ||
82 | silk_apply_sine_window_FLP( Wsig_ptr, x_buf_ptr, 2, psEnc->sCmn.la_pitch ); | ||
83 | |||
84 | /* Calculate autocorrelation sequence */ | ||
85 | silk_autocorrelation_FLP( auto_corr, Wsig, psEnc->sCmn.pitch_LPC_win_length, psEnc->sCmn.pitchEstimationLPCOrder + 1 ); | ||
86 | |||
87 | /* Add white noise, as a fraction of the energy */ | ||
88 | auto_corr[ 0 ] += auto_corr[ 0 ] * FIND_PITCH_WHITE_NOISE_FRACTION + 1; | ||
89 | |||
90 | /* Calculate the reflection coefficients using Schur */ | ||
91 | res_nrg = silk_schur_FLP( refl_coef, auto_corr, psEnc->sCmn.pitchEstimationLPCOrder ); | ||
92 | |||
93 | /* Prediction gain */ | ||
94 | psEncCtrl->predGain = auto_corr[ 0 ] / silk_max_float( res_nrg, 1.0f ); | ||
95 | |||
96 | /* Convert reflection coefficients to prediction coefficients */ | ||
97 | silk_k2a_FLP( A, refl_coef, psEnc->sCmn.pitchEstimationLPCOrder ); | ||
98 | |||
99 | /* Bandwidth expansion */ | ||
100 | silk_bwexpander_FLP( A, psEnc->sCmn.pitchEstimationLPCOrder, FIND_PITCH_BANDWIDTH_EXPANSION ); | ||
101 | |||
102 | /*****************************************/ | ||
103 | /* LPC analysis filtering */ | ||
104 | /*****************************************/ | ||
105 | silk_LPC_analysis_filter_FLP( res, A, x_buf, buf_len, psEnc->sCmn.pitchEstimationLPCOrder ); | ||
106 | |||
107 | if( psEnc->sCmn.indices.signalType != TYPE_NO_VOICE_ACTIVITY && psEnc->sCmn.first_frame_after_reset == 0 ) { | ||
108 | /* Threshold for pitch estimator */ | ||
109 | thrhld = 0.6f; | ||
110 | thrhld -= 0.004f * psEnc->sCmn.pitchEstimationLPCOrder; | ||
111 | thrhld -= 0.1f * psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f ); | ||
112 | thrhld -= 0.15f * (psEnc->sCmn.prevSignalType >> 1); | ||
113 | thrhld -= 0.1f * psEnc->sCmn.input_tilt_Q15 * ( 1.0f / 32768.0f ); | ||
114 | |||
115 | /*****************************************/ | ||
116 | /* Call Pitch estimator */ | ||
117 | /*****************************************/ | ||
118 | if( silk_pitch_analysis_core_FLP( res, psEncCtrl->pitchL, &psEnc->sCmn.indices.lagIndex, | ||
119 | &psEnc->sCmn.indices.contourIndex, &psEnc->LTPCorr, psEnc->sCmn.prevLag, psEnc->sCmn.pitchEstimationThreshold_Q16 / 65536.0f, | ||
120 | thrhld, psEnc->sCmn.fs_kHz, psEnc->sCmn.pitchEstimationComplexity, psEnc->sCmn.nb_subfr, arch ) == 0 ) | ||
121 | { | ||
122 | psEnc->sCmn.indices.signalType = TYPE_VOICED; | ||
123 | } else { | ||
124 | psEnc->sCmn.indices.signalType = TYPE_UNVOICED; | ||
125 | } | ||
126 | } else { | ||
127 | silk_memset( psEncCtrl->pitchL, 0, sizeof( psEncCtrl->pitchL ) ); | ||
128 | psEnc->sCmn.indices.lagIndex = 0; | ||
129 | psEnc->sCmn.indices.contourIndex = 0; | ||
130 | psEnc->LTPCorr = 0; | ||
131 | } | ||
132 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/float/find_pred_coefs_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/find_pred_coefs_FLP.c new file mode 100644 index 0000000000..dcf7c5202d --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/float/find_pred_coefs_FLP.c | |||
@@ -0,0 +1,116 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main_FLP.h" | ||
33 | |||
34 | /* Find LPC and LTP coefficients */ | ||
35 | void silk_find_pred_coefs_FLP( | ||
36 | silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ | ||
37 | silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ | ||
38 | const silk_float res_pitch[], /* I Residual from pitch analysis */ | ||
39 | const silk_float x[], /* I Speech signal */ | ||
40 | opus_int condCoding /* I The type of conditional coding to use */ | ||
41 | ) | ||
42 | { | ||
43 | opus_int i; | ||
44 | silk_float XXLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ]; | ||
45 | silk_float xXLTP[ MAX_NB_SUBFR * LTP_ORDER ]; | ||
46 | silk_float invGains[ MAX_NB_SUBFR ]; | ||
47 | opus_int16 NLSF_Q15[ MAX_LPC_ORDER ]; | ||
48 | const silk_float *x_ptr; | ||
49 | silk_float *x_pre_ptr, LPC_in_pre[ MAX_NB_SUBFR * MAX_LPC_ORDER + MAX_FRAME_LENGTH ]; | ||
50 | silk_float minInvGain; | ||
51 | |||
52 | /* Weighting for weighted least squares */ | ||
53 | for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { | ||
54 | silk_assert( psEncCtrl->Gains[ i ] > 0.0f ); | ||
55 | invGains[ i ] = 1.0f / psEncCtrl->Gains[ i ]; | ||
56 | } | ||
57 | |||
58 | if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { | ||
59 | /**********/ | ||
60 | /* VOICED */ | ||
61 | /**********/ | ||
62 | celt_assert( psEnc->sCmn.ltp_mem_length - psEnc->sCmn.predictLPCOrder >= psEncCtrl->pitchL[ 0 ] + LTP_ORDER / 2 ); | ||
63 | |||
64 | /* LTP analysis */ | ||
65 | silk_find_LTP_FLP( XXLTP, xXLTP, res_pitch, psEncCtrl->pitchL, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr ); | ||
66 | |||
67 | /* Quantize LTP gain parameters */ | ||
68 | silk_quant_LTP_gains_FLP( psEncCtrl->LTPCoef, psEnc->sCmn.indices.LTPIndex, &psEnc->sCmn.indices.PERIndex, | ||
69 | &psEnc->sCmn.sum_log_gain_Q7, &psEncCtrl->LTPredCodGain, XXLTP, xXLTP, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.arch ); | ||
70 | |||
71 | /* Control LTP scaling */ | ||
72 | silk_LTP_scale_ctrl_FLP( psEnc, psEncCtrl, condCoding ); | ||
73 | |||
74 | /* Create LTP residual */ | ||
75 | silk_LTP_analysis_filter_FLP( LPC_in_pre, x - psEnc->sCmn.predictLPCOrder, psEncCtrl->LTPCoef, | ||
76 | psEncCtrl->pitchL, invGains, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder ); | ||
77 | } else { | ||
78 | /************/ | ||
79 | /* UNVOICED */ | ||
80 | /************/ | ||
81 | /* Create signal with prepended subframes, scaled by inverse gains */ | ||
82 | x_ptr = x - psEnc->sCmn.predictLPCOrder; | ||
83 | x_pre_ptr = LPC_in_pre; | ||
84 | for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { | ||
85 | silk_scale_copy_vector_FLP( x_pre_ptr, x_ptr, invGains[ i ], | ||
86 | psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder ); | ||
87 | x_pre_ptr += psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder; | ||
88 | x_ptr += psEnc->sCmn.subfr_length; | ||
89 | } | ||
90 | silk_memset( psEncCtrl->LTPCoef, 0, psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( silk_float ) ); | ||
91 | psEncCtrl->LTPredCodGain = 0.0f; | ||
92 | psEnc->sCmn.sum_log_gain_Q7 = 0; | ||
93 | } | ||
94 | |||
95 | /* Limit on total predictive coding gain */ | ||
96 | if( psEnc->sCmn.first_frame_after_reset ) { | ||
97 | minInvGain = 1.0f / MAX_PREDICTION_POWER_GAIN_AFTER_RESET; | ||
98 | } else { | ||
99 | minInvGain = (silk_float)pow( 2, psEncCtrl->LTPredCodGain / 3 ) / MAX_PREDICTION_POWER_GAIN; | ||
100 | minInvGain /= 0.25f + 0.75f * psEncCtrl->coding_quality; | ||
101 | } | ||
102 | |||
103 | /* LPC_in_pre contains the LTP-filtered input for voiced, and the unfiltered input for unvoiced */ | ||
104 | silk_find_LPC_FLP( &psEnc->sCmn, NLSF_Q15, LPC_in_pre, minInvGain ); | ||
105 | |||
106 | /* Quantize LSFs */ | ||
107 | silk_process_NLSFs_FLP( &psEnc->sCmn, psEncCtrl->PredCoef, NLSF_Q15, psEnc->sCmn.prev_NLSFq_Q15 ); | ||
108 | |||
109 | /* Calculate residual energy using quantized LPC coefficients */ | ||
110 | silk_residual_energy_FLP( psEncCtrl->ResNrg, LPC_in_pre, psEncCtrl->PredCoef, psEncCtrl->Gains, | ||
111 | psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder ); | ||
112 | |||
113 | /* Copy to prediction struct for use in next frame for interpolation */ | ||
114 | silk_memcpy( psEnc->sCmn.prev_NLSFq_Q15, NLSF_Q15, sizeof( psEnc->sCmn.prev_NLSFq_Q15 ) ); | ||
115 | } | ||
116 | |||
diff --git a/lib/rbcodec/codecs/libopus/silk/float/inner_product_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/inner_product_FLP.c new file mode 100644 index 0000000000..cdd39d24ce --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/float/inner_product_FLP.c | |||
@@ -0,0 +1,59 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "SigProc_FLP.h" | ||
33 | |||
34 | /* inner product of two silk_float arrays, with result as double */ | ||
35 | double silk_inner_product_FLP( | ||
36 | const silk_float *data1, | ||
37 | const silk_float *data2, | ||
38 | opus_int dataSize | ||
39 | ) | ||
40 | { | ||
41 | opus_int i; | ||
42 | double result; | ||
43 | |||
44 | /* 4x unrolled loop */ | ||
45 | result = 0.0; | ||
46 | for( i = 0; i < dataSize - 3; i += 4 ) { | ||
47 | result += data1[ i + 0 ] * (double)data2[ i + 0 ] + | ||
48 | data1[ i + 1 ] * (double)data2[ i + 1 ] + | ||
49 | data1[ i + 2 ] * (double)data2[ i + 2 ] + | ||
50 | data1[ i + 3 ] * (double)data2[ i + 3 ]; | ||
51 | } | ||
52 | |||
53 | /* add any remaining products */ | ||
54 | for( ; i < dataSize; i++ ) { | ||
55 | result += data1[ i ] * (double)data2[ i ]; | ||
56 | } | ||
57 | |||
58 | return result; | ||
59 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/float/k2a_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/k2a_FLP.c new file mode 100644 index 0000000000..1448008dbb --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/float/k2a_FLP.c | |||
@@ -0,0 +1,54 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "SigProc_FLP.h" | ||
33 | |||
34 | /* step up function, converts reflection coefficients to prediction coefficients */ | ||
35 | void silk_k2a_FLP( | ||
36 | silk_float *A, /* O prediction coefficients [order] */ | ||
37 | const silk_float *rc, /* I reflection coefficients [order] */ | ||
38 | opus_int32 order /* I prediction order */ | ||
39 | ) | ||
40 | { | ||
41 | opus_int k, n; | ||
42 | silk_float rck, tmp1, tmp2; | ||
43 | |||
44 | for( k = 0; k < order; k++ ) { | ||
45 | rck = rc[ k ]; | ||
46 | for( n = 0; n < (k + 1) >> 1; n++ ) { | ||
47 | tmp1 = A[ n ]; | ||
48 | tmp2 = A[ k - n - 1 ]; | ||
49 | A[ n ] = tmp1 + tmp2 * rck; | ||
50 | A[ k - n - 1 ] = tmp2 + tmp1 * rck; | ||
51 | } | ||
52 | A[ k ] = -rck; | ||
53 | } | ||
54 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/float/main_FLP.h b/lib/rbcodec/codecs/libopus/silk/float/main_FLP.h new file mode 100644 index 0000000000..5dc0ccf4a4 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/float/main_FLP.h | |||
@@ -0,0 +1,286 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifndef SILK_MAIN_FLP_H | ||
29 | #define SILK_MAIN_FLP_H | ||
30 | |||
31 | #include "SigProc_FLP.h" | ||
32 | #include "SigProc_FIX.h" | ||
33 | #include "structs_FLP.h" | ||
34 | #include "main.h" | ||
35 | #include "define.h" | ||
36 | #include "debug.h" | ||
37 | #include "entenc.h" | ||
38 | |||
39 | #ifdef __cplusplus | ||
40 | extern "C" | ||
41 | { | ||
42 | #endif | ||
43 | |||
44 | #define silk_encoder_state_Fxx silk_encoder_state_FLP | ||
45 | #define silk_encode_do_VAD_Fxx silk_encode_do_VAD_FLP | ||
46 | #define silk_encode_frame_Fxx silk_encode_frame_FLP | ||
47 | |||
48 | /*********************/ | ||
49 | /* Encoder Functions */ | ||
50 | /*********************/ | ||
51 | |||
52 | /* High-pass filter with cutoff frequency adaptation based on pitch lag statistics */ | ||
53 | void silk_HP_variable_cutoff( | ||
54 | silk_encoder_state_Fxx state_Fxx[] /* I/O Encoder states */ | ||
55 | ); | ||
56 | |||
57 | /* Encoder main function */ | ||
58 | void silk_encode_do_VAD_FLP( | ||
59 | silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ | ||
60 | opus_int activity /* I Decision of Opus voice activity detector */ | ||
61 | ); | ||
62 | |||
63 | /* Encoder main function */ | ||
64 | opus_int silk_encode_frame_FLP( | ||
65 | silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ | ||
66 | opus_int32 *pnBytesOut, /* O Number of payload bytes; */ | ||
67 | ec_enc *psRangeEnc, /* I/O compressor data structure */ | ||
68 | opus_int condCoding, /* I The type of conditional coding to use */ | ||
69 | opus_int maxBits, /* I If > 0: maximum number of output bits */ | ||
70 | opus_int useCBR /* I Flag to force constant-bitrate operation */ | ||
71 | ); | ||
72 | |||
73 | /* Initializes the Silk encoder state */ | ||
74 | opus_int silk_init_encoder( | ||
75 | silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ | ||
76 | int arch /* I Run-tim architecture */ | ||
77 | ); | ||
78 | |||
79 | /* Control the Silk encoder */ | ||
80 | opus_int silk_control_encoder( | ||
81 | silk_encoder_state_FLP *psEnc, /* I/O Pointer to Silk encoder state FLP */ | ||
82 | silk_EncControlStruct *encControl, /* I Control structure */ | ||
83 | const opus_int allow_bw_switch, /* I Flag to allow switching audio bandwidth */ | ||
84 | const opus_int channelNb, /* I Channel number */ | ||
85 | const opus_int force_fs_kHz | ||
86 | ); | ||
87 | |||
88 | /**************************/ | ||
89 | /* Noise shaping analysis */ | ||
90 | /**************************/ | ||
91 | /* Compute noise shaping coefficients and initial gain values */ | ||
92 | void silk_noise_shape_analysis_FLP( | ||
93 | silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ | ||
94 | silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ | ||
95 | const silk_float *pitch_res, /* I LPC residual from pitch analysis */ | ||
96 | const silk_float *x /* I Input signal [frame_length + la_shape] */ | ||
97 | ); | ||
98 | |||
99 | /* Autocorrelations for a warped frequency axis */ | ||
100 | void silk_warped_autocorrelation_FLP( | ||
101 | silk_float *corr, /* O Result [order + 1] */ | ||
102 | const silk_float *input, /* I Input data to correlate */ | ||
103 | const silk_float warping, /* I Warping coefficient */ | ||
104 | const opus_int length, /* I Length of input */ | ||
105 | const opus_int order /* I Correlation order (even) */ | ||
106 | ); | ||
107 | |||
108 | /* Calculation of LTP state scaling */ | ||
109 | void silk_LTP_scale_ctrl_FLP( | ||
110 | silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ | ||
111 | silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ | ||
112 | opus_int condCoding /* I The type of conditional coding to use */ | ||
113 | ); | ||
114 | |||
115 | /**********************************************/ | ||
116 | /* Prediction Analysis */ | ||
117 | /**********************************************/ | ||
118 | /* Find pitch lags */ | ||
119 | void silk_find_pitch_lags_FLP( | ||
120 | silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ | ||
121 | silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ | ||
122 | silk_float res[], /* O Residual */ | ||
123 | const silk_float x[], /* I Speech signal */ | ||
124 | int arch /* I Run-time architecture */ | ||
125 | ); | ||
126 | |||
127 | /* Find LPC and LTP coefficients */ | ||
128 | void silk_find_pred_coefs_FLP( | ||
129 | silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ | ||
130 | silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ | ||
131 | const silk_float res_pitch[], /* I Residual from pitch analysis */ | ||
132 | const silk_float x[], /* I Speech signal */ | ||
133 | opus_int condCoding /* I The type of conditional coding to use */ | ||
134 | ); | ||
135 | |||
136 | /* LPC analysis */ | ||
137 | void silk_find_LPC_FLP( | ||
138 | silk_encoder_state *psEncC, /* I/O Encoder state */ | ||
139 | opus_int16 NLSF_Q15[], /* O NLSFs */ | ||
140 | const silk_float x[], /* I Input signal */ | ||
141 | const silk_float minInvGain /* I Prediction gain from LTP (dB) */ | ||
142 | ); | ||
143 | |||
144 | /* LTP analysis */ | ||
145 | void silk_find_LTP_FLP( | ||
146 | silk_float XX[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Weight for LTP quantization */ | ||
147 | silk_float xX[ MAX_NB_SUBFR * LTP_ORDER ], /* O Weight for LTP quantization */ | ||
148 | const silk_float r_ptr[], /* I LPC residual */ | ||
149 | const opus_int lag[ MAX_NB_SUBFR ], /* I LTP lags */ | ||
150 | const opus_int subfr_length, /* I Subframe length */ | ||
151 | const opus_int nb_subfr /* I number of subframes */ | ||
152 | ); | ||
153 | |||
154 | void silk_LTP_analysis_filter_FLP( | ||
155 | silk_float *LTP_res, /* O LTP res MAX_NB_SUBFR*(pre_lgth+subfr_lngth) */ | ||
156 | const silk_float *x, /* I Input signal, with preceding samples */ | ||
157 | const silk_float B[ LTP_ORDER * MAX_NB_SUBFR ], /* I LTP coefficients for each subframe */ | ||
158 | const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ | ||
159 | const silk_float invGains[ MAX_NB_SUBFR ], /* I Inverse quantization gains */ | ||
160 | const opus_int subfr_length, /* I Length of each subframe */ | ||
161 | const opus_int nb_subfr, /* I number of subframes */ | ||
162 | const opus_int pre_length /* I Preceding samples for each subframe */ | ||
163 | ); | ||
164 | |||
165 | /* Calculates residual energies of input subframes where all subframes have LPC_order */ | ||
166 | /* of preceding samples */ | ||
167 | void silk_residual_energy_FLP( | ||
168 | silk_float nrgs[ MAX_NB_SUBFR ], /* O Residual energy per subframe */ | ||
169 | const silk_float x[], /* I Input signal */ | ||
170 | silk_float a[ 2 ][ MAX_LPC_ORDER ], /* I AR coefs for each frame half */ | ||
171 | const silk_float gains[], /* I Quantization gains */ | ||
172 | const opus_int subfr_length, /* I Subframe length */ | ||
173 | const opus_int nb_subfr, /* I number of subframes */ | ||
174 | const opus_int LPC_order /* I LPC order */ | ||
175 | ); | ||
176 | |||
177 | /* 16th order LPC analysis filter */ | ||
178 | void silk_LPC_analysis_filter_FLP( | ||
179 | silk_float r_LPC[], /* O LPC residual signal */ | ||
180 | const silk_float PredCoef[], /* I LPC coefficients */ | ||
181 | const silk_float s[], /* I Input signal */ | ||
182 | const opus_int length, /* I Length of input signal */ | ||
183 | const opus_int Order /* I LPC order */ | ||
184 | ); | ||
185 | |||
186 | /* LTP tap quantizer */ | ||
187 | void silk_quant_LTP_gains_FLP( | ||
188 | silk_float B[ MAX_NB_SUBFR * LTP_ORDER ], /* O Quantized LTP gains */ | ||
189 | opus_int8 cbk_index[ MAX_NB_SUBFR ], /* O Codebook index */ | ||
190 | opus_int8 *periodicity_index, /* O Periodicity index */ | ||
191 | opus_int32 *sum_log_gain_Q7, /* I/O Cumulative max prediction gain */ | ||
192 | silk_float *pred_gain_dB, /* O LTP prediction gain */ | ||
193 | const silk_float XX[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* I Correlation matrix */ | ||
194 | const silk_float xX[ MAX_NB_SUBFR * LTP_ORDER ], /* I Correlation vector */ | ||
195 | const opus_int subfr_len, /* I Number of samples per subframe */ | ||
196 | const opus_int nb_subfr, /* I Number of subframes */ | ||
197 | int arch /* I Run-time architecture */ | ||
198 | ); | ||
199 | |||
200 | /* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */ | ||
201 | silk_float silk_residual_energy_covar_FLP( /* O Weighted residual energy */ | ||
202 | const silk_float *c, /* I Filter coefficients */ | ||
203 | silk_float *wXX, /* I/O Weighted correlation matrix, reg. out */ | ||
204 | const silk_float *wXx, /* I Weighted correlation vector */ | ||
205 | const silk_float wxx, /* I Weighted correlation value */ | ||
206 | const opus_int D /* I Dimension */ | ||
207 | ); | ||
208 | |||
209 | /* Processing of gains */ | ||
210 | void silk_process_gains_FLP( | ||
211 | silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ | ||
212 | silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ | ||
213 | opus_int condCoding /* I The type of conditional coding to use */ | ||
214 | ); | ||
215 | |||
216 | /******************/ | ||
217 | /* Linear Algebra */ | ||
218 | /******************/ | ||
219 | /* Calculates correlation matrix X'*X */ | ||
220 | void silk_corrMatrix_FLP( | ||
221 | const silk_float *x, /* I x vector [ L+order-1 ] used to create X */ | ||
222 | const opus_int L, /* I Length of vectors */ | ||
223 | const opus_int Order, /* I Max lag for correlation */ | ||
224 | silk_float *XX /* O X'*X correlation matrix [order x order] */ | ||
225 | ); | ||
226 | |||
227 | /* Calculates correlation vector X'*t */ | ||
228 | void silk_corrVector_FLP( | ||
229 | const silk_float *x, /* I x vector [L+order-1] used to create X */ | ||
230 | const silk_float *t, /* I Target vector [L] */ | ||
231 | const opus_int L, /* I Length of vecors */ | ||
232 | const opus_int Order, /* I Max lag for correlation */ | ||
233 | silk_float *Xt /* O X'*t correlation vector [order] */ | ||
234 | ); | ||
235 | |||
236 | /* Apply sine window to signal vector. */ | ||
237 | /* Window types: */ | ||
238 | /* 1 -> sine window from 0 to pi/2 */ | ||
239 | /* 2 -> sine window from pi/2 to pi */ | ||
240 | void silk_apply_sine_window_FLP( | ||
241 | silk_float px_win[], /* O Pointer to windowed signal */ | ||
242 | const silk_float px[], /* I Pointer to input signal */ | ||
243 | const opus_int win_type, /* I Selects a window type */ | ||
244 | const opus_int length /* I Window length, multiple of 4 */ | ||
245 | ); | ||
246 | |||
247 | /* Wrapper functions. Call flp / fix code */ | ||
248 | |||
249 | /* Convert AR filter coefficients to NLSF parameters */ | ||
250 | void silk_A2NLSF_FLP( | ||
251 | opus_int16 *NLSF_Q15, /* O NLSF vector [ LPC_order ] */ | ||
252 | const silk_float *pAR, /* I LPC coefficients [ LPC_order ] */ | ||
253 | const opus_int LPC_order /* I LPC order */ | ||
254 | ); | ||
255 | |||
256 | /* Convert NLSF parameters to AR prediction filter coefficients */ | ||
257 | void silk_NLSF2A_FLP( | ||
258 | silk_float *pAR, /* O LPC coefficients [ LPC_order ] */ | ||
259 | const opus_int16 *NLSF_Q15, /* I NLSF vector [ LPC_order ] */ | ||
260 | const opus_int LPC_order, /* I LPC order */ | ||
261 | int arch /* I Run-time architecture */ | ||
262 | ); | ||
263 | |||
264 | /* Limit, stabilize, and quantize NLSFs */ | ||
265 | void silk_process_NLSFs_FLP( | ||
266 | silk_encoder_state *psEncC, /* I/O Encoder state */ | ||
267 | silk_float PredCoef[ 2 ][ MAX_LPC_ORDER ], /* O Prediction coefficients */ | ||
268 | opus_int16 NLSF_Q15[ MAX_LPC_ORDER ], /* I/O Normalized LSFs (quant out) (0 - (2^15-1)) */ | ||
269 | const opus_int16 prev_NLSF_Q15[ MAX_LPC_ORDER ] /* I Previous Normalized LSFs (0 - (2^15-1)) */ | ||
270 | ); | ||
271 | |||
272 | /* Floating-point Silk NSQ wrapper */ | ||
273 | void silk_NSQ_wrapper_FLP( | ||
274 | silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ | ||
275 | silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ | ||
276 | SideInfoIndices *psIndices, /* I/O Quantization indices */ | ||
277 | silk_nsq_state *psNSQ, /* I/O Noise Shaping Quantzation state */ | ||
278 | opus_int8 pulses[], /* O Quantized pulse signal */ | ||
279 | const silk_float x[] /* I Prefiltered input signal */ | ||
280 | ); | ||
281 | |||
282 | #ifdef __cplusplus | ||
283 | } | ||
284 | #endif | ||
285 | |||
286 | #endif | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/float/noise_shape_analysis_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/noise_shape_analysis_FLP.c new file mode 100644 index 0000000000..cb3d8a50b7 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/float/noise_shape_analysis_FLP.c | |||
@@ -0,0 +1,350 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main_FLP.h" | ||
33 | #include "tuning_parameters.h" | ||
34 | |||
35 | /* Compute gain to make warped filter coefficients have a zero mean log frequency response on a */ | ||
36 | /* non-warped frequency scale. (So that it can be implemented with a minimum-phase monic filter.) */ | ||
37 | /* Note: A monic filter is one with the first coefficient equal to 1.0. In Silk we omit the first */ | ||
38 | /* coefficient in an array of coefficients, for monic filters. */ | ||
39 | static OPUS_INLINE silk_float warped_gain( | ||
40 | const silk_float *coefs, | ||
41 | silk_float lambda, | ||
42 | opus_int order | ||
43 | ) { | ||
44 | opus_int i; | ||
45 | silk_float gain; | ||
46 | |||
47 | lambda = -lambda; | ||
48 | gain = coefs[ order - 1 ]; | ||
49 | for( i = order - 2; i >= 0; i-- ) { | ||
50 | gain = lambda * gain + coefs[ i ]; | ||
51 | } | ||
52 | return (silk_float)( 1.0f / ( 1.0f - lambda * gain ) ); | ||
53 | } | ||
54 | |||
55 | /* Convert warped filter coefficients to monic pseudo-warped coefficients and limit maximum */ | ||
56 | /* amplitude of monic warped coefficients by using bandwidth expansion on the true coefficients */ | ||
57 | static OPUS_INLINE void warped_true2monic_coefs( | ||
58 | silk_float *coefs, | ||
59 | silk_float lambda, | ||
60 | silk_float limit, | ||
61 | opus_int order | ||
62 | ) { | ||
63 | opus_int i, iter, ind = 0; | ||
64 | silk_float tmp, maxabs, chirp, gain; | ||
65 | |||
66 | /* Convert to monic coefficients */ | ||
67 | for( i = order - 1; i > 0; i-- ) { | ||
68 | coefs[ i - 1 ] -= lambda * coefs[ i ]; | ||
69 | } | ||
70 | gain = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs[ 0 ] ); | ||
71 | for( i = 0; i < order; i++ ) { | ||
72 | coefs[ i ] *= gain; | ||
73 | } | ||
74 | |||
75 | /* Limit */ | ||
76 | for( iter = 0; iter < 10; iter++ ) { | ||
77 | /* Find maximum absolute value */ | ||
78 | maxabs = -1.0f; | ||
79 | for( i = 0; i < order; i++ ) { | ||
80 | tmp = silk_abs_float( coefs[ i ] ); | ||
81 | if( tmp > maxabs ) { | ||
82 | maxabs = tmp; | ||
83 | ind = i; | ||
84 | } | ||
85 | } | ||
86 | if( maxabs <= limit ) { | ||
87 | /* Coefficients are within range - done */ | ||
88 | return; | ||
89 | } | ||
90 | |||
91 | /* Convert back to true warped coefficients */ | ||
92 | for( i = 1; i < order; i++ ) { | ||
93 | coefs[ i - 1 ] += lambda * coefs[ i ]; | ||
94 | } | ||
95 | gain = 1.0f / gain; | ||
96 | for( i = 0; i < order; i++ ) { | ||
97 | coefs[ i ] *= gain; | ||
98 | } | ||
99 | |||
100 | /* Apply bandwidth expansion */ | ||
101 | chirp = 0.99f - ( 0.8f + 0.1f * iter ) * ( maxabs - limit ) / ( maxabs * ( ind + 1 ) ); | ||
102 | silk_bwexpander_FLP( coefs, order, chirp ); | ||
103 | |||
104 | /* Convert to monic warped coefficients */ | ||
105 | for( i = order - 1; i > 0; i-- ) { | ||
106 | coefs[ i - 1 ] -= lambda * coefs[ i ]; | ||
107 | } | ||
108 | gain = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs[ 0 ] ); | ||
109 | for( i = 0; i < order; i++ ) { | ||
110 | coefs[ i ] *= gain; | ||
111 | } | ||
112 | } | ||
113 | silk_assert( 0 ); | ||
114 | } | ||
115 | |||
116 | static OPUS_INLINE void limit_coefs( | ||
117 | silk_float *coefs, | ||
118 | silk_float limit, | ||
119 | opus_int order | ||
120 | ) { | ||
121 | opus_int i, iter, ind = 0; | ||
122 | silk_float tmp, maxabs, chirp; | ||
123 | |||
124 | for( iter = 0; iter < 10; iter++ ) { | ||
125 | /* Find maximum absolute value */ | ||
126 | maxabs = -1.0f; | ||
127 | for( i = 0; i < order; i++ ) { | ||
128 | tmp = silk_abs_float( coefs[ i ] ); | ||
129 | if( tmp > maxabs ) { | ||
130 | maxabs = tmp; | ||
131 | ind = i; | ||
132 | } | ||
133 | } | ||
134 | if( maxabs <= limit ) { | ||
135 | /* Coefficients are within range - done */ | ||
136 | return; | ||
137 | } | ||
138 | |||
139 | /* Apply bandwidth expansion */ | ||
140 | chirp = 0.99f - ( 0.8f + 0.1f * iter ) * ( maxabs - limit ) / ( maxabs * ( ind + 1 ) ); | ||
141 | silk_bwexpander_FLP( coefs, order, chirp ); | ||
142 | } | ||
143 | silk_assert( 0 ); | ||
144 | } | ||
145 | |||
146 | /* Compute noise shaping coefficients and initial gain values */ | ||
147 | void silk_noise_shape_analysis_FLP( | ||
148 | silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ | ||
149 | silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ | ||
150 | const silk_float *pitch_res, /* I LPC residual from pitch analysis */ | ||
151 | const silk_float *x /* I Input signal [frame_length + la_shape] */ | ||
152 | ) | ||
153 | { | ||
154 | silk_shape_state_FLP *psShapeSt = &psEnc->sShape; | ||
155 | opus_int k, nSamples, nSegs; | ||
156 | silk_float SNR_adj_dB, HarmShapeGain, Tilt; | ||
157 | silk_float nrg, log_energy, log_energy_prev, energy_variation; | ||
158 | silk_float BWExp, gain_mult, gain_add, strength, b, warping; | ||
159 | silk_float x_windowed[ SHAPE_LPC_WIN_MAX ]; | ||
160 | silk_float auto_corr[ MAX_SHAPE_LPC_ORDER + 1 ]; | ||
161 | silk_float rc[ MAX_SHAPE_LPC_ORDER + 1 ]; | ||
162 | const silk_float *x_ptr, *pitch_res_ptr; | ||
163 | |||
164 | /* Point to start of first LPC analysis block */ | ||
165 | x_ptr = x - psEnc->sCmn.la_shape; | ||
166 | |||
167 | /****************/ | ||
168 | /* GAIN CONTROL */ | ||
169 | /****************/ | ||
170 | SNR_adj_dB = psEnc->sCmn.SNR_dB_Q7 * ( 1 / 128.0f ); | ||
171 | |||
172 | /* Input quality is the average of the quality in the lowest two VAD bands */ | ||
173 | psEncCtrl->input_quality = 0.5f * ( psEnc->sCmn.input_quality_bands_Q15[ 0 ] + psEnc->sCmn.input_quality_bands_Q15[ 1 ] ) * ( 1.0f / 32768.0f ); | ||
174 | |||
175 | /* Coding quality level, between 0.0 and 1.0 */ | ||
176 | psEncCtrl->coding_quality = silk_sigmoid( 0.25f * ( SNR_adj_dB - 20.0f ) ); | ||
177 | |||
178 | if( psEnc->sCmn.useCBR == 0 ) { | ||
179 | /* Reduce coding SNR during low speech activity */ | ||
180 | b = 1.0f - psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f ); | ||
181 | SNR_adj_dB -= BG_SNR_DECR_dB * psEncCtrl->coding_quality * ( 0.5f + 0.5f * psEncCtrl->input_quality ) * b * b; | ||
182 | } | ||
183 | |||
184 | if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { | ||
185 | /* Reduce gains for periodic signals */ | ||
186 | SNR_adj_dB += HARM_SNR_INCR_dB * psEnc->LTPCorr; | ||
187 | } else { | ||
188 | /* For unvoiced signals and low-quality input, adjust the quality slower than SNR_dB setting */ | ||
189 | SNR_adj_dB += ( -0.4f * psEnc->sCmn.SNR_dB_Q7 * ( 1 / 128.0f ) + 6.0f ) * ( 1.0f - psEncCtrl->input_quality ); | ||
190 | } | ||
191 | |||
192 | /*************************/ | ||
193 | /* SPARSENESS PROCESSING */ | ||
194 | /*************************/ | ||
195 | /* Set quantizer offset */ | ||
196 | if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { | ||
197 | /* Initially set to 0; may be overruled in process_gains(..) */ | ||
198 | psEnc->sCmn.indices.quantOffsetType = 0; | ||
199 | } else { | ||
200 | /* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */ | ||
201 | nSamples = 2 * psEnc->sCmn.fs_kHz; | ||
202 | energy_variation = 0.0f; | ||
203 | log_energy_prev = 0.0f; | ||
204 | pitch_res_ptr = pitch_res; | ||
205 | nSegs = silk_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2; | ||
206 | for( k = 0; k < nSegs; k++ ) { | ||
207 | nrg = ( silk_float )nSamples + ( silk_float )silk_energy_FLP( pitch_res_ptr, nSamples ); | ||
208 | log_energy = silk_log2( nrg ); | ||
209 | if( k > 0 ) { | ||
210 | energy_variation += silk_abs_float( log_energy - log_energy_prev ); | ||
211 | } | ||
212 | log_energy_prev = log_energy; | ||
213 | pitch_res_ptr += nSamples; | ||
214 | } | ||
215 | |||
216 | /* Set quantization offset depending on sparseness measure */ | ||
217 | if( energy_variation > ENERGY_VARIATION_THRESHOLD_QNT_OFFSET * (nSegs-1) ) { | ||
218 | psEnc->sCmn.indices.quantOffsetType = 0; | ||
219 | } else { | ||
220 | psEnc->sCmn.indices.quantOffsetType = 1; | ||
221 | } | ||
222 | } | ||
223 | |||
224 | /*******************************/ | ||
225 | /* Control bandwidth expansion */ | ||
226 | /*******************************/ | ||
227 | /* More BWE for signals with high prediction gain */ | ||
228 | strength = FIND_PITCH_WHITE_NOISE_FRACTION * psEncCtrl->predGain; /* between 0.0 and 1.0 */ | ||
229 | BWExp = BANDWIDTH_EXPANSION / ( 1.0f + strength * strength ); | ||
230 | |||
231 | /* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */ | ||
232 | warping = (silk_float)psEnc->sCmn.warping_Q16 / 65536.0f + 0.01f * psEncCtrl->coding_quality; | ||
233 | |||
234 | /********************************************/ | ||
235 | /* Compute noise shaping AR coefs and gains */ | ||
236 | /********************************************/ | ||
237 | for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { | ||
238 | /* Apply window: sine slope followed by flat part followed by cosine slope */ | ||
239 | opus_int shift, slope_part, flat_part; | ||
240 | flat_part = psEnc->sCmn.fs_kHz * 3; | ||
241 | slope_part = ( psEnc->sCmn.shapeWinLength - flat_part ) / 2; | ||
242 | |||
243 | silk_apply_sine_window_FLP( x_windowed, x_ptr, 1, slope_part ); | ||
244 | shift = slope_part; | ||
245 | silk_memcpy( x_windowed + shift, x_ptr + shift, flat_part * sizeof(silk_float) ); | ||
246 | shift += flat_part; | ||
247 | silk_apply_sine_window_FLP( x_windowed + shift, x_ptr + shift, 2, slope_part ); | ||
248 | |||
249 | /* Update pointer: next LPC analysis block */ | ||
250 | x_ptr += psEnc->sCmn.subfr_length; | ||
251 | |||
252 | if( psEnc->sCmn.warping_Q16 > 0 ) { | ||
253 | /* Calculate warped auto correlation */ | ||
254 | silk_warped_autocorrelation_FLP( auto_corr, x_windowed, warping, | ||
255 | psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder ); | ||
256 | } else { | ||
257 | /* Calculate regular auto correlation */ | ||
258 | silk_autocorrelation_FLP( auto_corr, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1 ); | ||
259 | } | ||
260 | |||
261 | /* Add white noise, as a fraction of energy */ | ||
262 | auto_corr[ 0 ] += auto_corr[ 0 ] * SHAPE_WHITE_NOISE_FRACTION + 1.0f; | ||
263 | |||
264 | /* Convert correlations to prediction coefficients, and compute residual energy */ | ||
265 | nrg = silk_schur_FLP( rc, auto_corr, psEnc->sCmn.shapingLPCOrder ); | ||
266 | silk_k2a_FLP( &psEncCtrl->AR[ k * MAX_SHAPE_LPC_ORDER ], rc, psEnc->sCmn.shapingLPCOrder ); | ||
267 | psEncCtrl->Gains[ k ] = ( silk_float )sqrt( nrg ); | ||
268 | |||
269 | if( psEnc->sCmn.warping_Q16 > 0 ) { | ||
270 | /* Adjust gain for warping */ | ||
271 | psEncCtrl->Gains[ k ] *= warped_gain( &psEncCtrl->AR[ k * MAX_SHAPE_LPC_ORDER ], warping, psEnc->sCmn.shapingLPCOrder ); | ||
272 | } | ||
273 | |||
274 | /* Bandwidth expansion for synthesis filter shaping */ | ||
275 | silk_bwexpander_FLP( &psEncCtrl->AR[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder, BWExp ); | ||
276 | |||
277 | if( psEnc->sCmn.warping_Q16 > 0 ) { | ||
278 | /* Convert to monic warped prediction coefficients and limit absolute values */ | ||
279 | warped_true2monic_coefs( &psEncCtrl->AR[ k * MAX_SHAPE_LPC_ORDER ], warping, 3.999f, psEnc->sCmn.shapingLPCOrder ); | ||
280 | } else { | ||
281 | /* Limit absolute values */ | ||
282 | limit_coefs( &psEncCtrl->AR[ k * MAX_SHAPE_LPC_ORDER ], 3.999f, psEnc->sCmn.shapingLPCOrder ); | ||
283 | } | ||
284 | } | ||
285 | |||
286 | /*****************/ | ||
287 | /* Gain tweaking */ | ||
288 | /*****************/ | ||
289 | /* Increase gains during low speech activity */ | ||
290 | gain_mult = (silk_float)pow( 2.0f, -0.16f * SNR_adj_dB ); | ||
291 | gain_add = (silk_float)pow( 2.0f, 0.16f * MIN_QGAIN_DB ); | ||
292 | for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { | ||
293 | psEncCtrl->Gains[ k ] *= gain_mult; | ||
294 | psEncCtrl->Gains[ k ] += gain_add; | ||
295 | } | ||
296 | |||
297 | /************************************************/ | ||
298 | /* Control low-frequency shaping and noise tilt */ | ||
299 | /************************************************/ | ||
300 | /* Less low frequency shaping for noisy inputs */ | ||
301 | strength = LOW_FREQ_SHAPING * ( 1.0f + LOW_QUALITY_LOW_FREQ_SHAPING_DECR * ( psEnc->sCmn.input_quality_bands_Q15[ 0 ] * ( 1.0f / 32768.0f ) - 1.0f ) ); | ||
302 | strength *= psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f ); | ||
303 | if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { | ||
304 | /* Reduce low frequencies quantization noise for periodic signals, depending on pitch lag */ | ||
305 | /*f = 400; freqz([1, -0.98 + 2e-4 * f], [1, -0.97 + 7e-4 * f], 2^12, Fs); axis([0, 1000, -10, 1])*/ | ||
306 | for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { | ||
307 | b = 0.2f / psEnc->sCmn.fs_kHz + 3.0f / psEncCtrl->pitchL[ k ]; | ||
308 | psEncCtrl->LF_MA_shp[ k ] = -1.0f + b; | ||
309 | psEncCtrl->LF_AR_shp[ k ] = 1.0f - b - b * strength; | ||
310 | } | ||
311 | Tilt = - HP_NOISE_COEF - | ||
312 | (1 - HP_NOISE_COEF) * HARM_HP_NOISE_COEF * psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f ); | ||
313 | } else { | ||
314 | b = 1.3f / psEnc->sCmn.fs_kHz; | ||
315 | psEncCtrl->LF_MA_shp[ 0 ] = -1.0f + b; | ||
316 | psEncCtrl->LF_AR_shp[ 0 ] = 1.0f - b - b * strength * 0.6f; | ||
317 | for( k = 1; k < psEnc->sCmn.nb_subfr; k++ ) { | ||
318 | psEncCtrl->LF_MA_shp[ k ] = psEncCtrl->LF_MA_shp[ 0 ]; | ||
319 | psEncCtrl->LF_AR_shp[ k ] = psEncCtrl->LF_AR_shp[ 0 ]; | ||
320 | } | ||
321 | Tilt = -HP_NOISE_COEF; | ||
322 | } | ||
323 | |||
324 | /****************************/ | ||
325 | /* HARMONIC SHAPING CONTROL */ | ||
326 | /****************************/ | ||
327 | if( USE_HARM_SHAPING && psEnc->sCmn.indices.signalType == TYPE_VOICED ) { | ||
328 | /* Harmonic noise shaping */ | ||
329 | HarmShapeGain = HARMONIC_SHAPING; | ||
330 | |||
331 | /* More harmonic noise shaping for high bitrates or noisy input */ | ||
332 | HarmShapeGain += HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING * | ||
333 | ( 1.0f - ( 1.0f - psEncCtrl->coding_quality ) * psEncCtrl->input_quality ); | ||
334 | |||
335 | /* Less harmonic noise shaping for less periodic signals */ | ||
336 | HarmShapeGain *= ( silk_float )sqrt( psEnc->LTPCorr ); | ||
337 | } else { | ||
338 | HarmShapeGain = 0.0f; | ||
339 | } | ||
340 | |||
341 | /*************************/ | ||
342 | /* Smooth over subframes */ | ||
343 | /*************************/ | ||
344 | for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { | ||
345 | psShapeSt->HarmShapeGain_smth += SUBFR_SMTH_COEF * ( HarmShapeGain - psShapeSt->HarmShapeGain_smth ); | ||
346 | psEncCtrl->HarmShapeGain[ k ] = psShapeSt->HarmShapeGain_smth; | ||
347 | psShapeSt->Tilt_smth += SUBFR_SMTH_COEF * ( Tilt - psShapeSt->Tilt_smth ); | ||
348 | psEncCtrl->Tilt[ k ] = psShapeSt->Tilt_smth; | ||
349 | } | ||
350 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/float/pitch_analysis_core_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/pitch_analysis_core_FLP.c new file mode 100644 index 0000000000..f351bc3718 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/float/pitch_analysis_core_FLP.c | |||
@@ -0,0 +1,630 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | /***************************************************************************** | ||
33 | * Pitch analyser function | ||
34 | ******************************************************************************/ | ||
35 | #include "SigProc_FLP.h" | ||
36 | #include "SigProc_FIX.h" | ||
37 | #include "pitch_est_defines.h" | ||
38 | #include "pitch.h" | ||
39 | |||
40 | #define SCRATCH_SIZE 22 | ||
41 | |||
42 | /************************************************************/ | ||
43 | /* Internally used functions */ | ||
44 | /************************************************************/ | ||
45 | static void silk_P_Ana_calc_corr_st3( | ||
46 | silk_float cross_corr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */ | ||
47 | const silk_float frame[], /* I vector to correlate */ | ||
48 | opus_int start_lag, /* I start lag */ | ||
49 | opus_int sf_length, /* I sub frame length */ | ||
50 | opus_int nb_subfr, /* I number of subframes */ | ||
51 | opus_int complexity, /* I Complexity setting */ | ||
52 | int arch /* I Run-time architecture */ | ||
53 | ); | ||
54 | |||
55 | static void silk_P_Ana_calc_energy_st3( | ||
56 | silk_float energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */ | ||
57 | const silk_float frame[], /* I vector to correlate */ | ||
58 | opus_int start_lag, /* I start lag */ | ||
59 | opus_int sf_length, /* I sub frame length */ | ||
60 | opus_int nb_subfr, /* I number of subframes */ | ||
61 | opus_int complexity /* I Complexity setting */ | ||
62 | ); | ||
63 | |||
64 | /************************************************************/ | ||
65 | /* CORE PITCH ANALYSIS FUNCTION */ | ||
66 | /************************************************************/ | ||
67 | opus_int silk_pitch_analysis_core_FLP( /* O Voicing estimate: 0 voiced, 1 unvoiced */ | ||
68 | const silk_float *frame, /* I Signal of length PE_FRAME_LENGTH_MS*Fs_kHz */ | ||
69 | opus_int *pitch_out, /* O Pitch lag values [nb_subfr] */ | ||
70 | opus_int16 *lagIndex, /* O Lag Index */ | ||
71 | opus_int8 *contourIndex, /* O Pitch contour Index */ | ||
72 | silk_float *LTPCorr, /* I/O Normalized correlation; input: value from previous frame */ | ||
73 | opus_int prevLag, /* I Last lag of previous frame; set to zero is unvoiced */ | ||
74 | const silk_float search_thres1, /* I First stage threshold for lag candidates 0 - 1 */ | ||
75 | const silk_float search_thres2, /* I Final threshold for lag candidates 0 - 1 */ | ||
76 | const opus_int Fs_kHz, /* I sample frequency (kHz) */ | ||
77 | const opus_int complexity, /* I Complexity setting, 0-2, where 2 is highest */ | ||
78 | const opus_int nb_subfr, /* I Number of 5 ms subframes */ | ||
79 | int arch /* I Run-time architecture */ | ||
80 | ) | ||
81 | { | ||
82 | opus_int i, k, d, j; | ||
83 | silk_float frame_8kHz[ PE_MAX_FRAME_LENGTH_MS * 8 ]; | ||
84 | silk_float frame_4kHz[ PE_MAX_FRAME_LENGTH_MS * 4 ]; | ||
85 | opus_int16 frame_8_FIX[ PE_MAX_FRAME_LENGTH_MS * 8 ]; | ||
86 | opus_int16 frame_4_FIX[ PE_MAX_FRAME_LENGTH_MS * 4 ]; | ||
87 | opus_int32 filt_state[ 6 ]; | ||
88 | silk_float threshold, contour_bias; | ||
89 | silk_float C[ PE_MAX_NB_SUBFR][ (PE_MAX_LAG >> 1) + 5 ]; | ||
90 | opus_val32 xcorr[ PE_MAX_LAG_MS * 4 - PE_MIN_LAG_MS * 4 + 1 ]; | ||
91 | silk_float CC[ PE_NB_CBKS_STAGE2_EXT ]; | ||
92 | const silk_float *target_ptr, *basis_ptr; | ||
93 | double cross_corr, normalizer, energy, energy_tmp; | ||
94 | opus_int d_srch[ PE_D_SRCH_LENGTH ]; | ||
95 | opus_int16 d_comp[ (PE_MAX_LAG >> 1) + 5 ]; | ||
96 | opus_int length_d_srch, length_d_comp; | ||
97 | silk_float Cmax, CCmax, CCmax_b, CCmax_new_b, CCmax_new; | ||
98 | opus_int CBimax, CBimax_new, lag, start_lag, end_lag, lag_new; | ||
99 | opus_int cbk_size; | ||
100 | silk_float lag_log2, prevLag_log2, delta_lag_log2_sqr; | ||
101 | silk_float energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ]; | ||
102 | silk_float cross_corr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ]; | ||
103 | opus_int lag_counter; | ||
104 | opus_int frame_length, frame_length_8kHz, frame_length_4kHz; | ||
105 | opus_int sf_length, sf_length_8kHz, sf_length_4kHz; | ||
106 | opus_int min_lag, min_lag_8kHz, min_lag_4kHz; | ||
107 | opus_int max_lag, max_lag_8kHz, max_lag_4kHz; | ||
108 | opus_int nb_cbk_search; | ||
109 | const opus_int8 *Lag_CB_ptr; | ||
110 | |||
111 | /* Check for valid sampling frequency */ | ||
112 | celt_assert( Fs_kHz == 8 || Fs_kHz == 12 || Fs_kHz == 16 ); | ||
113 | |||
114 | /* Check for valid complexity setting */ | ||
115 | celt_assert( complexity >= SILK_PE_MIN_COMPLEX ); | ||
116 | celt_assert( complexity <= SILK_PE_MAX_COMPLEX ); | ||
117 | |||
118 | silk_assert( search_thres1 >= 0.0f && search_thres1 <= 1.0f ); | ||
119 | silk_assert( search_thres2 >= 0.0f && search_thres2 <= 1.0f ); | ||
120 | |||
121 | /* Set up frame lengths max / min lag for the sampling frequency */ | ||
122 | frame_length = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * Fs_kHz; | ||
123 | frame_length_4kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 4; | ||
124 | frame_length_8kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 8; | ||
125 | sf_length = PE_SUBFR_LENGTH_MS * Fs_kHz; | ||
126 | sf_length_4kHz = PE_SUBFR_LENGTH_MS * 4; | ||
127 | sf_length_8kHz = PE_SUBFR_LENGTH_MS * 8; | ||
128 | min_lag = PE_MIN_LAG_MS * Fs_kHz; | ||
129 | min_lag_4kHz = PE_MIN_LAG_MS * 4; | ||
130 | min_lag_8kHz = PE_MIN_LAG_MS * 8; | ||
131 | max_lag = PE_MAX_LAG_MS * Fs_kHz - 1; | ||
132 | max_lag_4kHz = PE_MAX_LAG_MS * 4; | ||
133 | max_lag_8kHz = PE_MAX_LAG_MS * 8 - 1; | ||
134 | |||
135 | /* Resample from input sampled at Fs_kHz to 8 kHz */ | ||
136 | if( Fs_kHz == 16 ) { | ||
137 | /* Resample to 16 -> 8 khz */ | ||
138 | opus_int16 frame_16_FIX[ 16 * PE_MAX_FRAME_LENGTH_MS ]; | ||
139 | silk_float2short_array( frame_16_FIX, frame, frame_length ); | ||
140 | silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) ); | ||
141 | silk_resampler_down2( filt_state, frame_8_FIX, frame_16_FIX, frame_length ); | ||
142 | silk_short2float_array( frame_8kHz, frame_8_FIX, frame_length_8kHz ); | ||
143 | } else if( Fs_kHz == 12 ) { | ||
144 | /* Resample to 12 -> 8 khz */ | ||
145 | opus_int16 frame_12_FIX[ 12 * PE_MAX_FRAME_LENGTH_MS ]; | ||
146 | silk_float2short_array( frame_12_FIX, frame, frame_length ); | ||
147 | silk_memset( filt_state, 0, 6 * sizeof( opus_int32 ) ); | ||
148 | silk_resampler_down2_3( filt_state, frame_8_FIX, frame_12_FIX, frame_length ); | ||
149 | silk_short2float_array( frame_8kHz, frame_8_FIX, frame_length_8kHz ); | ||
150 | } else { | ||
151 | celt_assert( Fs_kHz == 8 ); | ||
152 | silk_float2short_array( frame_8_FIX, frame, frame_length_8kHz ); | ||
153 | } | ||
154 | |||
155 | /* Decimate again to 4 kHz */ | ||
156 | silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) ); | ||
157 | silk_resampler_down2( filt_state, frame_4_FIX, frame_8_FIX, frame_length_8kHz ); | ||
158 | silk_short2float_array( frame_4kHz, frame_4_FIX, frame_length_4kHz ); | ||
159 | |||
160 | /* Low-pass filter */ | ||
161 | for( i = frame_length_4kHz - 1; i > 0; i-- ) { | ||
162 | frame_4kHz[ i ] = silk_ADD_SAT16( frame_4kHz[ i ], frame_4kHz[ i - 1 ] ); | ||
163 | } | ||
164 | |||
165 | /****************************************************************************** | ||
166 | * FIRST STAGE, operating in 4 khz | ||
167 | ******************************************************************************/ | ||
168 | silk_memset(C, 0, sizeof(silk_float) * nb_subfr * ((PE_MAX_LAG >> 1) + 5)); | ||
169 | target_ptr = &frame_4kHz[ silk_LSHIFT( sf_length_4kHz, 2 ) ]; | ||
170 | for( k = 0; k < nb_subfr >> 1; k++ ) { | ||
171 | /* Check that we are within range of the array */ | ||
172 | celt_assert( target_ptr >= frame_4kHz ); | ||
173 | celt_assert( target_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz ); | ||
174 | |||
175 | basis_ptr = target_ptr - min_lag_4kHz; | ||
176 | |||
177 | /* Check that we are within range of the array */ | ||
178 | celt_assert( basis_ptr >= frame_4kHz ); | ||
179 | celt_assert( basis_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz ); | ||
180 | |||
181 | celt_pitch_xcorr( target_ptr, target_ptr-max_lag_4kHz, xcorr, sf_length_8kHz, max_lag_4kHz - min_lag_4kHz + 1, arch ); | ||
182 | |||
183 | /* Calculate first vector products before loop */ | ||
184 | cross_corr = xcorr[ max_lag_4kHz - min_lag_4kHz ]; | ||
185 | normalizer = silk_energy_FLP( target_ptr, sf_length_8kHz ) + | ||
186 | silk_energy_FLP( basis_ptr, sf_length_8kHz ) + | ||
187 | sf_length_8kHz * 4000.0f; | ||
188 | |||
189 | C[ 0 ][ min_lag_4kHz ] += (silk_float)( 2 * cross_corr / normalizer ); | ||
190 | |||
191 | /* From now on normalizer is computed recursively */ | ||
192 | for( d = min_lag_4kHz + 1; d <= max_lag_4kHz; d++ ) { | ||
193 | basis_ptr--; | ||
194 | |||
195 | /* Check that we are within range of the array */ | ||
196 | silk_assert( basis_ptr >= frame_4kHz ); | ||
197 | silk_assert( basis_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz ); | ||
198 | |||
199 | cross_corr = xcorr[ max_lag_4kHz - d ]; | ||
200 | |||
201 | /* Add contribution of new sample and remove contribution from oldest sample */ | ||
202 | normalizer += | ||
203 | basis_ptr[ 0 ] * (double)basis_ptr[ 0 ] - | ||
204 | basis_ptr[ sf_length_8kHz ] * (double)basis_ptr[ sf_length_8kHz ]; | ||
205 | C[ 0 ][ d ] += (silk_float)( 2 * cross_corr / normalizer ); | ||
206 | } | ||
207 | /* Update target pointer */ | ||
208 | target_ptr += sf_length_8kHz; | ||
209 | } | ||
210 | |||
211 | /* Apply short-lag bias */ | ||
212 | for( i = max_lag_4kHz; i >= min_lag_4kHz; i-- ) { | ||
213 | C[ 0 ][ i ] -= C[ 0 ][ i ] * i / 4096.0f; | ||
214 | } | ||
215 | |||
216 | /* Sort */ | ||
217 | length_d_srch = 4 + 2 * complexity; | ||
218 | celt_assert( 3 * length_d_srch <= PE_D_SRCH_LENGTH ); | ||
219 | silk_insertion_sort_decreasing_FLP( &C[ 0 ][ min_lag_4kHz ], d_srch, max_lag_4kHz - min_lag_4kHz + 1, length_d_srch ); | ||
220 | |||
221 | /* Escape if correlation is very low already here */ | ||
222 | Cmax = C[ 0 ][ min_lag_4kHz ]; | ||
223 | if( Cmax < 0.2f ) { | ||
224 | silk_memset( pitch_out, 0, nb_subfr * sizeof( opus_int ) ); | ||
225 | *LTPCorr = 0.0f; | ||
226 | *lagIndex = 0; | ||
227 | *contourIndex = 0; | ||
228 | return 1; | ||
229 | } | ||
230 | |||
231 | threshold = search_thres1 * Cmax; | ||
232 | for( i = 0; i < length_d_srch; i++ ) { | ||
233 | /* Convert to 8 kHz indices for the sorted correlation that exceeds the threshold */ | ||
234 | if( C[ 0 ][ min_lag_4kHz + i ] > threshold ) { | ||
235 | d_srch[ i ] = silk_LSHIFT( d_srch[ i ] + min_lag_4kHz, 1 ); | ||
236 | } else { | ||
237 | length_d_srch = i; | ||
238 | break; | ||
239 | } | ||
240 | } | ||
241 | celt_assert( length_d_srch > 0 ); | ||
242 | |||
243 | for( i = min_lag_8kHz - 5; i < max_lag_8kHz + 5; i++ ) { | ||
244 | d_comp[ i ] = 0; | ||
245 | } | ||
246 | for( i = 0; i < length_d_srch; i++ ) { | ||
247 | d_comp[ d_srch[ i ] ] = 1; | ||
248 | } | ||
249 | |||
250 | /* Convolution */ | ||
251 | for( i = max_lag_8kHz + 3; i >= min_lag_8kHz; i-- ) { | ||
252 | d_comp[ i ] += d_comp[ i - 1 ] + d_comp[ i - 2 ]; | ||
253 | } | ||
254 | |||
255 | length_d_srch = 0; | ||
256 | for( i = min_lag_8kHz; i < max_lag_8kHz + 1; i++ ) { | ||
257 | if( d_comp[ i + 1 ] > 0 ) { | ||
258 | d_srch[ length_d_srch ] = i; | ||
259 | length_d_srch++; | ||
260 | } | ||
261 | } | ||
262 | |||
263 | /* Convolution */ | ||
264 | for( i = max_lag_8kHz + 3; i >= min_lag_8kHz; i-- ) { | ||
265 | d_comp[ i ] += d_comp[ i - 1 ] + d_comp[ i - 2 ] + d_comp[ i - 3 ]; | ||
266 | } | ||
267 | |||
268 | length_d_comp = 0; | ||
269 | for( i = min_lag_8kHz; i < max_lag_8kHz + 4; i++ ) { | ||
270 | if( d_comp[ i ] > 0 ) { | ||
271 | d_comp[ length_d_comp ] = (opus_int16)( i - 2 ); | ||
272 | length_d_comp++; | ||
273 | } | ||
274 | } | ||
275 | |||
276 | /********************************************************************************** | ||
277 | ** SECOND STAGE, operating at 8 kHz, on lag sections with high correlation | ||
278 | *************************************************************************************/ | ||
279 | /********************************************************************************* | ||
280 | * Find energy of each subframe projected onto its history, for a range of delays | ||
281 | *********************************************************************************/ | ||
282 | silk_memset( C, 0, PE_MAX_NB_SUBFR*((PE_MAX_LAG >> 1) + 5) * sizeof(silk_float)); | ||
283 | |||
284 | if( Fs_kHz == 8 ) { | ||
285 | target_ptr = &frame[ PE_LTP_MEM_LENGTH_MS * 8 ]; | ||
286 | } else { | ||
287 | target_ptr = &frame_8kHz[ PE_LTP_MEM_LENGTH_MS * 8 ]; | ||
288 | } | ||
289 | for( k = 0; k < nb_subfr; k++ ) { | ||
290 | energy_tmp = silk_energy_FLP( target_ptr, sf_length_8kHz ) + 1.0; | ||
291 | for( j = 0; j < length_d_comp; j++ ) { | ||
292 | d = d_comp[ j ]; | ||
293 | basis_ptr = target_ptr - d; | ||
294 | cross_corr = silk_inner_product_FLP( basis_ptr, target_ptr, sf_length_8kHz ); | ||
295 | if( cross_corr > 0.0f ) { | ||
296 | energy = silk_energy_FLP( basis_ptr, sf_length_8kHz ); | ||
297 | C[ k ][ d ] = (silk_float)( 2 * cross_corr / ( energy + energy_tmp ) ); | ||
298 | } else { | ||
299 | C[ k ][ d ] = 0.0f; | ||
300 | } | ||
301 | } | ||
302 | target_ptr += sf_length_8kHz; | ||
303 | } | ||
304 | |||
305 | /* search over lag range and lags codebook */ | ||
306 | /* scale factor for lag codebook, as a function of center lag */ | ||
307 | |||
308 | CCmax = 0.0f; /* This value doesn't matter */ | ||
309 | CCmax_b = -1000.0f; | ||
310 | |||
311 | CBimax = 0; /* To avoid returning undefined lag values */ | ||
312 | lag = -1; /* To check if lag with strong enough correlation has been found */ | ||
313 | |||
314 | if( prevLag > 0 ) { | ||
315 | if( Fs_kHz == 12 ) { | ||
316 | prevLag = silk_LSHIFT( prevLag, 1 ) / 3; | ||
317 | } else if( Fs_kHz == 16 ) { | ||
318 | prevLag = silk_RSHIFT( prevLag, 1 ); | ||
319 | } | ||
320 | prevLag_log2 = silk_log2( (silk_float)prevLag ); | ||
321 | } else { | ||
322 | prevLag_log2 = 0; | ||
323 | } | ||
324 | |||
325 | /* Set up stage 2 codebook based on number of subframes */ | ||
326 | if( nb_subfr == PE_MAX_NB_SUBFR ) { | ||
327 | cbk_size = PE_NB_CBKS_STAGE2_EXT; | ||
328 | Lag_CB_ptr = &silk_CB_lags_stage2[ 0 ][ 0 ]; | ||
329 | if( Fs_kHz == 8 && complexity > SILK_PE_MIN_COMPLEX ) { | ||
330 | /* If input is 8 khz use a larger codebook here because it is last stage */ | ||
331 | nb_cbk_search = PE_NB_CBKS_STAGE2_EXT; | ||
332 | } else { | ||
333 | nb_cbk_search = PE_NB_CBKS_STAGE2; | ||
334 | } | ||
335 | } else { | ||
336 | cbk_size = PE_NB_CBKS_STAGE2_10MS; | ||
337 | Lag_CB_ptr = &silk_CB_lags_stage2_10_ms[ 0 ][ 0 ]; | ||
338 | nb_cbk_search = PE_NB_CBKS_STAGE2_10MS; | ||
339 | } | ||
340 | |||
341 | for( k = 0; k < length_d_srch; k++ ) { | ||
342 | d = d_srch[ k ]; | ||
343 | for( j = 0; j < nb_cbk_search; j++ ) { | ||
344 | CC[j] = 0.0f; | ||
345 | for( i = 0; i < nb_subfr; i++ ) { | ||
346 | /* Try all codebooks */ | ||
347 | CC[ j ] += C[ i ][ d + matrix_ptr( Lag_CB_ptr, i, j, cbk_size )]; | ||
348 | } | ||
349 | } | ||
350 | /* Find best codebook */ | ||
351 | CCmax_new = -1000.0f; | ||
352 | CBimax_new = 0; | ||
353 | for( i = 0; i < nb_cbk_search; i++ ) { | ||
354 | if( CC[ i ] > CCmax_new ) { | ||
355 | CCmax_new = CC[ i ]; | ||
356 | CBimax_new = i; | ||
357 | } | ||
358 | } | ||
359 | |||
360 | /* Bias towards shorter lags */ | ||
361 | lag_log2 = silk_log2( (silk_float)d ); | ||
362 | CCmax_new_b = CCmax_new - PE_SHORTLAG_BIAS * nb_subfr * lag_log2; | ||
363 | |||
364 | /* Bias towards previous lag */ | ||
365 | if( prevLag > 0 ) { | ||
366 | delta_lag_log2_sqr = lag_log2 - prevLag_log2; | ||
367 | delta_lag_log2_sqr *= delta_lag_log2_sqr; | ||
368 | CCmax_new_b -= PE_PREVLAG_BIAS * nb_subfr * (*LTPCorr) * delta_lag_log2_sqr / ( delta_lag_log2_sqr + 0.5f ); | ||
369 | } | ||
370 | |||
371 | if( CCmax_new_b > CCmax_b && /* Find maximum biased correlation */ | ||
372 | CCmax_new > nb_subfr * search_thres2 /* Correlation needs to be high enough to be voiced */ | ||
373 | ) { | ||
374 | CCmax_b = CCmax_new_b; | ||
375 | CCmax = CCmax_new; | ||
376 | lag = d; | ||
377 | CBimax = CBimax_new; | ||
378 | } | ||
379 | } | ||
380 | |||
381 | if( lag == -1 ) { | ||
382 | /* No suitable candidate found */ | ||
383 | silk_memset( pitch_out, 0, PE_MAX_NB_SUBFR * sizeof(opus_int) ); | ||
384 | *LTPCorr = 0.0f; | ||
385 | *lagIndex = 0; | ||
386 | *contourIndex = 0; | ||
387 | return 1; | ||
388 | } | ||
389 | |||
390 | /* Output normalized correlation */ | ||
391 | *LTPCorr = (silk_float)( CCmax / nb_subfr ); | ||
392 | silk_assert( *LTPCorr >= 0.0f ); | ||
393 | |||
394 | if( Fs_kHz > 8 ) { | ||
395 | /* Search in original signal */ | ||
396 | |||
397 | /* Compensate for decimation */ | ||
398 | silk_assert( lag == silk_SAT16( lag ) ); | ||
399 | if( Fs_kHz == 12 ) { | ||
400 | lag = silk_RSHIFT_ROUND( silk_SMULBB( lag, 3 ), 1 ); | ||
401 | } else { /* Fs_kHz == 16 */ | ||
402 | lag = silk_LSHIFT( lag, 1 ); | ||
403 | } | ||
404 | |||
405 | lag = silk_LIMIT_int( lag, min_lag, max_lag ); | ||
406 | start_lag = silk_max_int( lag - 2, min_lag ); | ||
407 | end_lag = silk_min_int( lag + 2, max_lag ); | ||
408 | lag_new = lag; /* to avoid undefined lag */ | ||
409 | CBimax = 0; /* to avoid undefined lag */ | ||
410 | |||
411 | CCmax = -1000.0f; | ||
412 | |||
413 | /* Calculate the correlations and energies needed in stage 3 */ | ||
414 | silk_P_Ana_calc_corr_st3( cross_corr_st3, frame, start_lag, sf_length, nb_subfr, complexity, arch ); | ||
415 | silk_P_Ana_calc_energy_st3( energies_st3, frame, start_lag, sf_length, nb_subfr, complexity ); | ||
416 | |||
417 | lag_counter = 0; | ||
418 | silk_assert( lag == silk_SAT16( lag ) ); | ||
419 | contour_bias = PE_FLATCONTOUR_BIAS / lag; | ||
420 | |||
421 | /* Set up cbk parameters according to complexity setting and frame length */ | ||
422 | if( nb_subfr == PE_MAX_NB_SUBFR ) { | ||
423 | nb_cbk_search = (opus_int)silk_nb_cbk_searchs_stage3[ complexity ]; | ||
424 | cbk_size = PE_NB_CBKS_STAGE3_MAX; | ||
425 | Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ]; | ||
426 | } else { | ||
427 | nb_cbk_search = PE_NB_CBKS_STAGE3_10MS; | ||
428 | cbk_size = PE_NB_CBKS_STAGE3_10MS; | ||
429 | Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ]; | ||
430 | } | ||
431 | |||
432 | target_ptr = &frame[ PE_LTP_MEM_LENGTH_MS * Fs_kHz ]; | ||
433 | energy_tmp = silk_energy_FLP( target_ptr, nb_subfr * sf_length ) + 1.0; | ||
434 | for( d = start_lag; d <= end_lag; d++ ) { | ||
435 | for( j = 0; j < nb_cbk_search; j++ ) { | ||
436 | cross_corr = 0.0; | ||
437 | energy = energy_tmp; | ||
438 | for( k = 0; k < nb_subfr; k++ ) { | ||
439 | cross_corr += cross_corr_st3[ k ][ j ][ lag_counter ]; | ||
440 | energy += energies_st3[ k ][ j ][ lag_counter ]; | ||
441 | } | ||
442 | if( cross_corr > 0.0 ) { | ||
443 | CCmax_new = (silk_float)( 2 * cross_corr / energy ); | ||
444 | /* Reduce depending on flatness of contour */ | ||
445 | CCmax_new *= 1.0f - contour_bias * j; | ||
446 | } else { | ||
447 | CCmax_new = 0.0f; | ||
448 | } | ||
449 | |||
450 | if( CCmax_new > CCmax && ( d + (opus_int)silk_CB_lags_stage3[ 0 ][ j ] ) <= max_lag ) { | ||
451 | CCmax = CCmax_new; | ||
452 | lag_new = d; | ||
453 | CBimax = j; | ||
454 | } | ||
455 | } | ||
456 | lag_counter++; | ||
457 | } | ||
458 | |||
459 | for( k = 0; k < nb_subfr; k++ ) { | ||
460 | pitch_out[ k ] = lag_new + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size ); | ||
461 | pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], min_lag, PE_MAX_LAG_MS * Fs_kHz ); | ||
462 | } | ||
463 | *lagIndex = (opus_int16)( lag_new - min_lag ); | ||
464 | *contourIndex = (opus_int8)CBimax; | ||
465 | } else { /* Fs_kHz == 8 */ | ||
466 | /* Save Lags */ | ||
467 | for( k = 0; k < nb_subfr; k++ ) { | ||
468 | pitch_out[ k ] = lag + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size ); | ||
469 | pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], min_lag_8kHz, PE_MAX_LAG_MS * 8 ); | ||
470 | } | ||
471 | *lagIndex = (opus_int16)( lag - min_lag_8kHz ); | ||
472 | *contourIndex = (opus_int8)CBimax; | ||
473 | } | ||
474 | celt_assert( *lagIndex >= 0 ); | ||
475 | /* return as voiced */ | ||
476 | return 0; | ||
477 | } | ||
478 | |||
479 | /*********************************************************************** | ||
480 | * Calculates the correlations used in stage 3 search. In order to cover | ||
481 | * the whole lag codebook for all the searched offset lags (lag +- 2), | ||
482 | * the following correlations are needed in each sub frame: | ||
483 | * | ||
484 | * sf1: lag range [-8,...,7] total 16 correlations | ||
485 | * sf2: lag range [-4,...,4] total 9 correlations | ||
486 | * sf3: lag range [-3,....4] total 8 correltions | ||
487 | * sf4: lag range [-6,....8] total 15 correlations | ||
488 | * | ||
489 | * In total 48 correlations. The direct implementation computed in worst | ||
490 | * case 4*12*5 = 240 correlations, but more likely around 120. | ||
491 | ***********************************************************************/ | ||
492 | static void silk_P_Ana_calc_corr_st3( | ||
493 | silk_float cross_corr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */ | ||
494 | const silk_float frame[], /* I vector to correlate */ | ||
495 | opus_int start_lag, /* I start lag */ | ||
496 | opus_int sf_length, /* I sub frame length */ | ||
497 | opus_int nb_subfr, /* I number of subframes */ | ||
498 | opus_int complexity, /* I Complexity setting */ | ||
499 | int arch /* I Run-time architecture */ | ||
500 | ) | ||
501 | { | ||
502 | const silk_float *target_ptr; | ||
503 | opus_int i, j, k, lag_counter, lag_low, lag_high; | ||
504 | opus_int nb_cbk_search, delta, idx, cbk_size; | ||
505 | silk_float scratch_mem[ SCRATCH_SIZE ]; | ||
506 | opus_val32 xcorr[ SCRATCH_SIZE ]; | ||
507 | const opus_int8 *Lag_range_ptr, *Lag_CB_ptr; | ||
508 | |||
509 | celt_assert( complexity >= SILK_PE_MIN_COMPLEX ); | ||
510 | celt_assert( complexity <= SILK_PE_MAX_COMPLEX ); | ||
511 | |||
512 | if( nb_subfr == PE_MAX_NB_SUBFR ) { | ||
513 | Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ]; | ||
514 | Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ]; | ||
515 | nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ]; | ||
516 | cbk_size = PE_NB_CBKS_STAGE3_MAX; | ||
517 | } else { | ||
518 | celt_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1); | ||
519 | Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ]; | ||
520 | Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ]; | ||
521 | nb_cbk_search = PE_NB_CBKS_STAGE3_10MS; | ||
522 | cbk_size = PE_NB_CBKS_STAGE3_10MS; | ||
523 | } | ||
524 | |||
525 | target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ]; /* Pointer to middle of frame */ | ||
526 | for( k = 0; k < nb_subfr; k++ ) { | ||
527 | lag_counter = 0; | ||
528 | |||
529 | /* Calculate the correlations for each subframe */ | ||
530 | lag_low = matrix_ptr( Lag_range_ptr, k, 0, 2 ); | ||
531 | lag_high = matrix_ptr( Lag_range_ptr, k, 1, 2 ); | ||
532 | silk_assert(lag_high-lag_low+1 <= SCRATCH_SIZE); | ||
533 | celt_pitch_xcorr( target_ptr, target_ptr - start_lag - lag_high, xcorr, sf_length, lag_high - lag_low + 1, arch ); | ||
534 | for( j = lag_low; j <= lag_high; j++ ) { | ||
535 | silk_assert( lag_counter < SCRATCH_SIZE ); | ||
536 | scratch_mem[ lag_counter ] = xcorr[ lag_high - j ]; | ||
537 | lag_counter++; | ||
538 | } | ||
539 | |||
540 | delta = matrix_ptr( Lag_range_ptr, k, 0, 2 ); | ||
541 | for( i = 0; i < nb_cbk_search; i++ ) { | ||
542 | /* Fill out the 3 dim array that stores the correlations for */ | ||
543 | /* each code_book vector for each start lag */ | ||
544 | idx = matrix_ptr( Lag_CB_ptr, k, i, cbk_size ) - delta; | ||
545 | for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) { | ||
546 | silk_assert( idx + j < SCRATCH_SIZE ); | ||
547 | silk_assert( idx + j < lag_counter ); | ||
548 | cross_corr_st3[ k ][ i ][ j ] = scratch_mem[ idx + j ]; | ||
549 | } | ||
550 | } | ||
551 | target_ptr += sf_length; | ||
552 | } | ||
553 | } | ||
554 | |||
555 | /********************************************************************/ | ||
556 | /* Calculate the energies for first two subframes. The energies are */ | ||
557 | /* calculated recursively. */ | ||
558 | /********************************************************************/ | ||
559 | static void silk_P_Ana_calc_energy_st3( | ||
560 | silk_float energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */ | ||
561 | const silk_float frame[], /* I vector to correlate */ | ||
562 | opus_int start_lag, /* I start lag */ | ||
563 | opus_int sf_length, /* I sub frame length */ | ||
564 | opus_int nb_subfr, /* I number of subframes */ | ||
565 | opus_int complexity /* I Complexity setting */ | ||
566 | ) | ||
567 | { | ||
568 | const silk_float *target_ptr, *basis_ptr; | ||
569 | double energy; | ||
570 | opus_int k, i, j, lag_counter; | ||
571 | opus_int nb_cbk_search, delta, idx, cbk_size, lag_diff; | ||
572 | silk_float scratch_mem[ SCRATCH_SIZE ]; | ||
573 | const opus_int8 *Lag_range_ptr, *Lag_CB_ptr; | ||
574 | |||
575 | celt_assert( complexity >= SILK_PE_MIN_COMPLEX ); | ||
576 | celt_assert( complexity <= SILK_PE_MAX_COMPLEX ); | ||
577 | |||
578 | if( nb_subfr == PE_MAX_NB_SUBFR ) { | ||
579 | Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ]; | ||
580 | Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ]; | ||
581 | nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ]; | ||
582 | cbk_size = PE_NB_CBKS_STAGE3_MAX; | ||
583 | } else { | ||
584 | celt_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1); | ||
585 | Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ]; | ||
586 | Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ]; | ||
587 | nb_cbk_search = PE_NB_CBKS_STAGE3_10MS; | ||
588 | cbk_size = PE_NB_CBKS_STAGE3_10MS; | ||
589 | } | ||
590 | |||
591 | target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ]; | ||
592 | for( k = 0; k < nb_subfr; k++ ) { | ||
593 | lag_counter = 0; | ||
594 | |||
595 | /* Calculate the energy for first lag */ | ||
596 | basis_ptr = target_ptr - ( start_lag + matrix_ptr( Lag_range_ptr, k, 0, 2 ) ); | ||
597 | energy = silk_energy_FLP( basis_ptr, sf_length ) + 1e-3; | ||
598 | silk_assert( energy >= 0.0 ); | ||
599 | scratch_mem[lag_counter] = (silk_float)energy; | ||
600 | lag_counter++; | ||
601 | |||
602 | lag_diff = ( matrix_ptr( Lag_range_ptr, k, 1, 2 ) - matrix_ptr( Lag_range_ptr, k, 0, 2 ) + 1 ); | ||
603 | for( i = 1; i < lag_diff; i++ ) { | ||
604 | /* remove part outside new window */ | ||
605 | energy -= basis_ptr[sf_length - i] * (double)basis_ptr[sf_length - i]; | ||
606 | silk_assert( energy >= 0.0 ); | ||
607 | |||
608 | /* add part that comes into window */ | ||
609 | energy += basis_ptr[ -i ] * (double)basis_ptr[ -i ]; | ||
610 | silk_assert( energy >= 0.0 ); | ||
611 | silk_assert( lag_counter < SCRATCH_SIZE ); | ||
612 | scratch_mem[lag_counter] = (silk_float)energy; | ||
613 | lag_counter++; | ||
614 | } | ||
615 | |||
616 | delta = matrix_ptr( Lag_range_ptr, k, 0, 2 ); | ||
617 | for( i = 0; i < nb_cbk_search; i++ ) { | ||
618 | /* Fill out the 3 dim array that stores the correlations for */ | ||
619 | /* each code_book vector for each start lag */ | ||
620 | idx = matrix_ptr( Lag_CB_ptr, k, i, cbk_size ) - delta; | ||
621 | for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) { | ||
622 | silk_assert( idx + j < SCRATCH_SIZE ); | ||
623 | silk_assert( idx + j < lag_counter ); | ||
624 | energies_st3[ k ][ i ][ j ] = scratch_mem[ idx + j ]; | ||
625 | silk_assert( energies_st3[ k ][ i ][ j ] >= 0.0f ); | ||
626 | } | ||
627 | } | ||
628 | target_ptr += sf_length; | ||
629 | } | ||
630 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/float/process_gains_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/process_gains_FLP.c new file mode 100644 index 0000000000..c0da0dae44 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/float/process_gains_FLP.c | |||
@@ -0,0 +1,103 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main_FLP.h" | ||
33 | #include "tuning_parameters.h" | ||
34 | |||
35 | /* Processing of gains */ | ||
36 | void silk_process_gains_FLP( | ||
37 | silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ | ||
38 | silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ | ||
39 | opus_int condCoding /* I The type of conditional coding to use */ | ||
40 | ) | ||
41 | { | ||
42 | silk_shape_state_FLP *psShapeSt = &psEnc->sShape; | ||
43 | opus_int k; | ||
44 | opus_int32 pGains_Q16[ MAX_NB_SUBFR ]; | ||
45 | silk_float s, InvMaxSqrVal, gain, quant_offset; | ||
46 | |||
47 | /* Gain reduction when LTP coding gain is high */ | ||
48 | if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { | ||
49 | s = 1.0f - 0.5f * silk_sigmoid( 0.25f * ( psEncCtrl->LTPredCodGain - 12.0f ) ); | ||
50 | for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { | ||
51 | psEncCtrl->Gains[ k ] *= s; | ||
52 | } | ||
53 | } | ||
54 | |||
55 | /* Limit the quantized signal */ | ||
56 | InvMaxSqrVal = ( silk_float )( pow( 2.0f, 0.33f * ( 21.0f - psEnc->sCmn.SNR_dB_Q7 * ( 1 / 128.0f ) ) ) / psEnc->sCmn.subfr_length ); | ||
57 | |||
58 | for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { | ||
59 | /* Soft limit on ratio residual energy and squared gains */ | ||
60 | gain = psEncCtrl->Gains[ k ]; | ||
61 | gain = ( silk_float )sqrt( gain * gain + psEncCtrl->ResNrg[ k ] * InvMaxSqrVal ); | ||
62 | psEncCtrl->Gains[ k ] = silk_min_float( gain, 32767.0f ); | ||
63 | } | ||
64 | |||
65 | /* Prepare gains for noise shaping quantization */ | ||
66 | for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { | ||
67 | pGains_Q16[ k ] = (opus_int32)( psEncCtrl->Gains[ k ] * 65536.0f ); | ||
68 | } | ||
69 | |||
70 | /* Save unquantized gains and gain Index */ | ||
71 | silk_memcpy( psEncCtrl->GainsUnq_Q16, pGains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) ); | ||
72 | psEncCtrl->lastGainIndexPrev = psShapeSt->LastGainIndex; | ||
73 | |||
74 | /* Quantize gains */ | ||
75 | silk_gains_quant( psEnc->sCmn.indices.GainsIndices, pGains_Q16, | ||
76 | &psShapeSt->LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr ); | ||
77 | |||
78 | /* Overwrite unquantized gains with quantized gains and convert back to Q0 from Q16 */ | ||
79 | for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { | ||
80 | psEncCtrl->Gains[ k ] = pGains_Q16[ k ] / 65536.0f; | ||
81 | } | ||
82 | |||
83 | /* Set quantizer offset for voiced signals. Larger offset when LTP coding gain is low or tilt is high (ie low-pass) */ | ||
84 | if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { | ||
85 | if( psEncCtrl->LTPredCodGain + psEnc->sCmn.input_tilt_Q15 * ( 1.0f / 32768.0f ) > 1.0f ) { | ||
86 | psEnc->sCmn.indices.quantOffsetType = 0; | ||
87 | } else { | ||
88 | psEnc->sCmn.indices.quantOffsetType = 1; | ||
89 | } | ||
90 | } | ||
91 | |||
92 | /* Quantizer boundary adjustment */ | ||
93 | quant_offset = silk_Quantization_Offsets_Q10[ psEnc->sCmn.indices.signalType >> 1 ][ psEnc->sCmn.indices.quantOffsetType ] / 1024.0f; | ||
94 | psEncCtrl->Lambda = LAMBDA_OFFSET | ||
95 | + LAMBDA_DELAYED_DECISIONS * psEnc->sCmn.nStatesDelayedDecision | ||
96 | + LAMBDA_SPEECH_ACT * psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f ) | ||
97 | + LAMBDA_INPUT_QUALITY * psEncCtrl->input_quality | ||
98 | + LAMBDA_CODING_QUALITY * psEncCtrl->coding_quality | ||
99 | + LAMBDA_QUANT_OFFSET * quant_offset; | ||
100 | |||
101 | silk_assert( psEncCtrl->Lambda > 0.0f ); | ||
102 | silk_assert( psEncCtrl->Lambda < 2.0f ); | ||
103 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/float/regularize_correlations_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/regularize_correlations_FLP.c new file mode 100644 index 0000000000..df4612604c --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/float/regularize_correlations_FLP.c | |||
@@ -0,0 +1,48 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main_FLP.h" | ||
33 | |||
34 | /* Add noise to matrix diagonal */ | ||
35 | void silk_regularize_correlations_FLP( | ||
36 | silk_float *XX, /* I/O Correlation matrices */ | ||
37 | silk_float *xx, /* I/O Correlation values */ | ||
38 | const silk_float noise, /* I Noise energy to add */ | ||
39 | const opus_int D /* I Dimension of XX */ | ||
40 | ) | ||
41 | { | ||
42 | opus_int i; | ||
43 | |||
44 | for( i = 0; i < D; i++ ) { | ||
45 | matrix_ptr( &XX[ 0 ], i, i, D ) += noise; | ||
46 | } | ||
47 | xx[ 0 ] += noise; | ||
48 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/float/residual_energy_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/residual_energy_FLP.c new file mode 100644 index 0000000000..1bd07b33a4 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/float/residual_energy_FLP.c | |||
@@ -0,0 +1,117 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main_FLP.h" | ||
33 | |||
34 | #define MAX_ITERATIONS_RESIDUAL_NRG 10 | ||
35 | #define REGULARIZATION_FACTOR 1e-8f | ||
36 | |||
37 | /* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */ | ||
38 | silk_float silk_residual_energy_covar_FLP( /* O Weighted residual energy */ | ||
39 | const silk_float *c, /* I Filter coefficients */ | ||
40 | silk_float *wXX, /* I/O Weighted correlation matrix, reg. out */ | ||
41 | const silk_float *wXx, /* I Weighted correlation vector */ | ||
42 | const silk_float wxx, /* I Weighted correlation value */ | ||
43 | const opus_int D /* I Dimension */ | ||
44 | ) | ||
45 | { | ||
46 | opus_int i, j, k; | ||
47 | silk_float tmp, nrg = 0.0f, regularization; | ||
48 | |||
49 | /* Safety checks */ | ||
50 | celt_assert( D >= 0 ); | ||
51 | |||
52 | regularization = REGULARIZATION_FACTOR * ( wXX[ 0 ] + wXX[ D * D - 1 ] ); | ||
53 | for( k = 0; k < MAX_ITERATIONS_RESIDUAL_NRG; k++ ) { | ||
54 | nrg = wxx; | ||
55 | |||
56 | tmp = 0.0f; | ||
57 | for( i = 0; i < D; i++ ) { | ||
58 | tmp += wXx[ i ] * c[ i ]; | ||
59 | } | ||
60 | nrg -= 2.0f * tmp; | ||
61 | |||
62 | /* compute c' * wXX * c, assuming wXX is symmetric */ | ||
63 | for( i = 0; i < D; i++ ) { | ||
64 | tmp = 0.0f; | ||
65 | for( j = i + 1; j < D; j++ ) { | ||
66 | tmp += matrix_c_ptr( wXX, i, j, D ) * c[ j ]; | ||
67 | } | ||
68 | nrg += c[ i ] * ( 2.0f * tmp + matrix_c_ptr( wXX, i, i, D ) * c[ i ] ); | ||
69 | } | ||
70 | if( nrg > 0 ) { | ||
71 | break; | ||
72 | } else { | ||
73 | /* Add white noise */ | ||
74 | for( i = 0; i < D; i++ ) { | ||
75 | matrix_c_ptr( wXX, i, i, D ) += regularization; | ||
76 | } | ||
77 | /* Increase noise for next run */ | ||
78 | regularization *= 2.0f; | ||
79 | } | ||
80 | } | ||
81 | if( k == MAX_ITERATIONS_RESIDUAL_NRG ) { | ||
82 | silk_assert( nrg == 0 ); | ||
83 | nrg = 1.0f; | ||
84 | } | ||
85 | |||
86 | return nrg; | ||
87 | } | ||
88 | |||
89 | /* Calculates residual energies of input subframes where all subframes have LPC_order */ | ||
90 | /* of preceding samples */ | ||
91 | void silk_residual_energy_FLP( | ||
92 | silk_float nrgs[ MAX_NB_SUBFR ], /* O Residual energy per subframe */ | ||
93 | const silk_float x[], /* I Input signal */ | ||
94 | silk_float a[ 2 ][ MAX_LPC_ORDER ], /* I AR coefs for each frame half */ | ||
95 | const silk_float gains[], /* I Quantization gains */ | ||
96 | const opus_int subfr_length, /* I Subframe length */ | ||
97 | const opus_int nb_subfr, /* I number of subframes */ | ||
98 | const opus_int LPC_order /* I LPC order */ | ||
99 | ) | ||
100 | { | ||
101 | opus_int shift; | ||
102 | silk_float *LPC_res_ptr, LPC_res[ ( MAX_FRAME_LENGTH + MAX_NB_SUBFR * MAX_LPC_ORDER ) / 2 ]; | ||
103 | |||
104 | LPC_res_ptr = LPC_res + LPC_order; | ||
105 | shift = LPC_order + subfr_length; | ||
106 | |||
107 | /* Filter input to create the LPC residual for each frame half, and measure subframe energies */ | ||
108 | silk_LPC_analysis_filter_FLP( LPC_res, a[ 0 ], x + 0 * shift, 2 * shift, LPC_order ); | ||
109 | nrgs[ 0 ] = ( silk_float )( gains[ 0 ] * gains[ 0 ] * silk_energy_FLP( LPC_res_ptr + 0 * shift, subfr_length ) ); | ||
110 | nrgs[ 1 ] = ( silk_float )( gains[ 1 ] * gains[ 1 ] * silk_energy_FLP( LPC_res_ptr + 1 * shift, subfr_length ) ); | ||
111 | |||
112 | if( nb_subfr == MAX_NB_SUBFR ) { | ||
113 | silk_LPC_analysis_filter_FLP( LPC_res, a[ 1 ], x + 2 * shift, 2 * shift, LPC_order ); | ||
114 | nrgs[ 2 ] = ( silk_float )( gains[ 2 ] * gains[ 2 ] * silk_energy_FLP( LPC_res_ptr + 0 * shift, subfr_length ) ); | ||
115 | nrgs[ 3 ] = ( silk_float )( gains[ 3 ] * gains[ 3 ] * silk_energy_FLP( LPC_res_ptr + 1 * shift, subfr_length ) ); | ||
116 | } | ||
117 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/float/scale_copy_vector_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/scale_copy_vector_FLP.c new file mode 100644 index 0000000000..20db32b3b1 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/float/scale_copy_vector_FLP.c | |||
@@ -0,0 +1,57 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "SigProc_FLP.h" | ||
33 | |||
34 | /* copy and multiply a vector by a constant */ | ||
35 | void silk_scale_copy_vector_FLP( | ||
36 | silk_float *data_out, | ||
37 | const silk_float *data_in, | ||
38 | silk_float gain, | ||
39 | opus_int dataSize | ||
40 | ) | ||
41 | { | ||
42 | opus_int i, dataSize4; | ||
43 | |||
44 | /* 4x unrolled loop */ | ||
45 | dataSize4 = dataSize & 0xFFFC; | ||
46 | for( i = 0; i < dataSize4; i += 4 ) { | ||
47 | data_out[ i + 0 ] = gain * data_in[ i + 0 ]; | ||
48 | data_out[ i + 1 ] = gain * data_in[ i + 1 ]; | ||
49 | data_out[ i + 2 ] = gain * data_in[ i + 2 ]; | ||
50 | data_out[ i + 3 ] = gain * data_in[ i + 3 ]; | ||
51 | } | ||
52 | |||
53 | /* any remaining elements */ | ||
54 | for( ; i < dataSize; i++ ) { | ||
55 | data_out[ i ] = gain * data_in[ i ]; | ||
56 | } | ||
57 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/float/scale_vector_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/scale_vector_FLP.c new file mode 100644 index 0000000000..108fdcbed5 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/float/scale_vector_FLP.c | |||
@@ -0,0 +1,56 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "SigProc_FLP.h" | ||
33 | |||
34 | /* multiply a vector by a constant */ | ||
35 | void silk_scale_vector_FLP( | ||
36 | silk_float *data1, | ||
37 | silk_float gain, | ||
38 | opus_int dataSize | ||
39 | ) | ||
40 | { | ||
41 | opus_int i, dataSize4; | ||
42 | |||
43 | /* 4x unrolled loop */ | ||
44 | dataSize4 = dataSize & 0xFFFC; | ||
45 | for( i = 0; i < dataSize4; i += 4 ) { | ||
46 | data1[ i + 0 ] *= gain; | ||
47 | data1[ i + 1 ] *= gain; | ||
48 | data1[ i + 2 ] *= gain; | ||
49 | data1[ i + 3 ] *= gain; | ||
50 | } | ||
51 | |||
52 | /* any remaining elements */ | ||
53 | for( ; i < dataSize; i++ ) { | ||
54 | data1[ i ] *= gain; | ||
55 | } | ||
56 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/float/schur_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/schur_FLP.c new file mode 100644 index 0000000000..8526c748d3 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/float/schur_FLP.c | |||
@@ -0,0 +1,70 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "SigProc_FLP.h" | ||
33 | |||
34 | silk_float silk_schur_FLP( /* O returns residual energy */ | ||
35 | silk_float refl_coef[], /* O reflection coefficients (length order) */ | ||
36 | const silk_float auto_corr[], /* I autocorrelation sequence (length order+1) */ | ||
37 | opus_int order /* I order */ | ||
38 | ) | ||
39 | { | ||
40 | opus_int k, n; | ||
41 | double C[ SILK_MAX_ORDER_LPC + 1 ][ 2 ]; | ||
42 | double Ctmp1, Ctmp2, rc_tmp; | ||
43 | |||
44 | celt_assert( order >= 0 && order <= SILK_MAX_ORDER_LPC ); | ||
45 | |||
46 | /* Copy correlations */ | ||
47 | k = 0; | ||
48 | do { | ||
49 | C[ k ][ 0 ] = C[ k ][ 1 ] = auto_corr[ k ]; | ||
50 | } while( ++k <= order ); | ||
51 | |||
52 | for( k = 0; k < order; k++ ) { | ||
53 | /* Get reflection coefficient */ | ||
54 | rc_tmp = -C[ k + 1 ][ 0 ] / silk_max_float( C[ 0 ][ 1 ], 1e-9f ); | ||
55 | |||
56 | /* Save the output */ | ||
57 | refl_coef[ k ] = (silk_float)rc_tmp; | ||
58 | |||
59 | /* Update correlations */ | ||
60 | for( n = 0; n < order - k; n++ ) { | ||
61 | Ctmp1 = C[ n + k + 1 ][ 0 ]; | ||
62 | Ctmp2 = C[ n ][ 1 ]; | ||
63 | C[ n + k + 1 ][ 0 ] = Ctmp1 + Ctmp2 * rc_tmp; | ||
64 | C[ n ][ 1 ] = Ctmp2 + Ctmp1 * rc_tmp; | ||
65 | } | ||
66 | } | ||
67 | |||
68 | /* Return residual energy */ | ||
69 | return (silk_float)C[ 0 ][ 1 ]; | ||
70 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/float/sort_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/sort_FLP.c new file mode 100644 index 0000000000..0e18f31950 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/float/sort_FLP.c | |||
@@ -0,0 +1,83 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | /* Insertion sort (fast for already almost sorted arrays): */ | ||
33 | /* Best case: O(n) for an already sorted array */ | ||
34 | /* Worst case: O(n^2) for an inversely sorted array */ | ||
35 | |||
36 | #include "typedef.h" | ||
37 | #include "SigProc_FLP.h" | ||
38 | |||
39 | void silk_insertion_sort_decreasing_FLP( | ||
40 | silk_float *a, /* I/O Unsorted / Sorted vector */ | ||
41 | opus_int *idx, /* O Index vector for the sorted elements */ | ||
42 | const opus_int L, /* I Vector length */ | ||
43 | const opus_int K /* I Number of correctly sorted positions */ | ||
44 | ) | ||
45 | { | ||
46 | silk_float value; | ||
47 | opus_int i, j; | ||
48 | |||
49 | /* Safety checks */ | ||
50 | celt_assert( K > 0 ); | ||
51 | celt_assert( L > 0 ); | ||
52 | celt_assert( L >= K ); | ||
53 | |||
54 | /* Write start indices in index vector */ | ||
55 | for( i = 0; i < K; i++ ) { | ||
56 | idx[ i ] = i; | ||
57 | } | ||
58 | |||
59 | /* Sort vector elements by value, decreasing order */ | ||
60 | for( i = 1; i < K; i++ ) { | ||
61 | value = a[ i ]; | ||
62 | for( j = i - 1; ( j >= 0 ) && ( value > a[ j ] ); j-- ) { | ||
63 | a[ j + 1 ] = a[ j ]; /* Shift value */ | ||
64 | idx[ j + 1 ] = idx[ j ]; /* Shift index */ | ||
65 | } | ||
66 | a[ j + 1 ] = value; /* Write value */ | ||
67 | idx[ j + 1 ] = i; /* Write index */ | ||
68 | } | ||
69 | |||
70 | /* If less than L values are asked check the remaining values, */ | ||
71 | /* but only spend CPU to ensure that the K first values are correct */ | ||
72 | for( i = K; i < L; i++ ) { | ||
73 | value = a[ i ]; | ||
74 | if( value > a[ K - 1 ] ) { | ||
75 | for( j = K - 2; ( j >= 0 ) && ( value > a[ j ] ); j-- ) { | ||
76 | a[ j + 1 ] = a[ j ]; /* Shift value */ | ||
77 | idx[ j + 1 ] = idx[ j ]; /* Shift index */ | ||
78 | } | ||
79 | a[ j + 1 ] = value; /* Write value */ | ||
80 | idx[ j + 1 ] = i; /* Write index */ | ||
81 | } | ||
82 | } | ||
83 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/float/structs_FLP.h b/lib/rbcodec/codecs/libopus/silk/float/structs_FLP.h new file mode 100644 index 0000000000..3150b386e4 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/float/structs_FLP.h | |||
@@ -0,0 +1,112 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifndef SILK_STRUCTS_FLP_H | ||
29 | #define SILK_STRUCTS_FLP_H | ||
30 | |||
31 | #include "typedef.h" | ||
32 | #include "main.h" | ||
33 | #include "structs.h" | ||
34 | |||
35 | #ifdef __cplusplus | ||
36 | extern "C" | ||
37 | { | ||
38 | #endif | ||
39 | |||
40 | /********************************/ | ||
41 | /* Noise shaping analysis state */ | ||
42 | /********************************/ | ||
43 | typedef struct { | ||
44 | opus_int8 LastGainIndex; | ||
45 | silk_float HarmShapeGain_smth; | ||
46 | silk_float Tilt_smth; | ||
47 | } silk_shape_state_FLP; | ||
48 | |||
49 | /********************************/ | ||
50 | /* Encoder state FLP */ | ||
51 | /********************************/ | ||
52 | typedef struct { | ||
53 | silk_encoder_state sCmn; /* Common struct, shared with fixed-point code */ | ||
54 | silk_shape_state_FLP sShape; /* Noise shaping state */ | ||
55 | |||
56 | /* Buffer for find pitch and noise shape analysis */ | ||
57 | silk_float x_buf[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ];/* Buffer for find pitch and noise shape analysis */ | ||
58 | silk_float LTPCorr; /* Normalized correlation from pitch lag estimator */ | ||
59 | } silk_encoder_state_FLP; | ||
60 | |||
61 | /************************/ | ||
62 | /* Encoder control FLP */ | ||
63 | /************************/ | ||
64 | typedef struct { | ||
65 | /* Prediction and coding parameters */ | ||
66 | silk_float Gains[ MAX_NB_SUBFR ]; | ||
67 | silk_float PredCoef[ 2 ][ MAX_LPC_ORDER ]; /* holds interpolated and final coefficients */ | ||
68 | silk_float LTPCoef[LTP_ORDER * MAX_NB_SUBFR]; | ||
69 | silk_float LTP_scale; | ||
70 | opus_int pitchL[ MAX_NB_SUBFR ]; | ||
71 | |||
72 | /* Noise shaping parameters */ | ||
73 | silk_float AR[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ]; | ||
74 | silk_float LF_MA_shp[ MAX_NB_SUBFR ]; | ||
75 | silk_float LF_AR_shp[ MAX_NB_SUBFR ]; | ||
76 | silk_float Tilt[ MAX_NB_SUBFR ]; | ||
77 | silk_float HarmShapeGain[ MAX_NB_SUBFR ]; | ||
78 | silk_float Lambda; | ||
79 | silk_float input_quality; | ||
80 | silk_float coding_quality; | ||
81 | |||
82 | /* Measures */ | ||
83 | silk_float predGain; | ||
84 | silk_float LTPredCodGain; | ||
85 | silk_float ResNrg[ MAX_NB_SUBFR ]; /* Residual energy per subframe */ | ||
86 | |||
87 | /* Parameters for CBR mode */ | ||
88 | opus_int32 GainsUnq_Q16[ MAX_NB_SUBFR ]; | ||
89 | opus_int8 lastGainIndexPrev; | ||
90 | } silk_encoder_control_FLP; | ||
91 | |||
92 | /************************/ | ||
93 | /* Encoder Super Struct */ | ||
94 | /************************/ | ||
95 | typedef struct { | ||
96 | silk_encoder_state_FLP state_Fxx[ ENCODER_NUM_CHANNELS ]; | ||
97 | stereo_enc_state sStereo; | ||
98 | opus_int32 nBitsUsedLBRR; | ||
99 | opus_int32 nBitsExceeded; | ||
100 | opus_int nChannelsAPI; | ||
101 | opus_int nChannelsInternal; | ||
102 | opus_int nPrevChannelsInternal; | ||
103 | opus_int timeSinceSwitchAllowed_ms; | ||
104 | opus_int allowBandwidthSwitch; | ||
105 | opus_int prev_decode_only_middle; | ||
106 | } silk_encoder; | ||
107 | |||
108 | #ifdef __cplusplus | ||
109 | } | ||
110 | #endif | ||
111 | |||
112 | #endif | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/float/warped_autocorrelation_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/warped_autocorrelation_FLP.c new file mode 100644 index 0000000000..09186e73d4 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/float/warped_autocorrelation_FLP.c | |||
@@ -0,0 +1,73 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main_FLP.h" | ||
33 | |||
34 | /* Autocorrelations for a warped frequency axis */ | ||
35 | void silk_warped_autocorrelation_FLP( | ||
36 | silk_float *corr, /* O Result [order + 1] */ | ||
37 | const silk_float *input, /* I Input data to correlate */ | ||
38 | const silk_float warping, /* I Warping coefficient */ | ||
39 | const opus_int length, /* I Length of input */ | ||
40 | const opus_int order /* I Correlation order (even) */ | ||
41 | ) | ||
42 | { | ||
43 | opus_int n, i; | ||
44 | double tmp1, tmp2; | ||
45 | double state[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 }; | ||
46 | double C[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 }; | ||
47 | |||
48 | /* Order must be even */ | ||
49 | celt_assert( ( order & 1 ) == 0 ); | ||
50 | |||
51 | /* Loop over samples */ | ||
52 | for( n = 0; n < length; n++ ) { | ||
53 | tmp1 = input[ n ]; | ||
54 | /* Loop over allpass sections */ | ||
55 | for( i = 0; i < order; i += 2 ) { | ||
56 | /* Output of allpass section */ | ||
57 | tmp2 = state[ i ] + warping * ( state[ i + 1 ] - tmp1 ); | ||
58 | state[ i ] = tmp1; | ||
59 | C[ i ] += state[ 0 ] * tmp1; | ||
60 | /* Output of allpass section */ | ||
61 | tmp1 = state[ i + 1 ] + warping * ( state[ i + 2 ] - tmp2 ); | ||
62 | state[ i + 1 ] = tmp2; | ||
63 | C[ i + 1 ] += state[ 0 ] * tmp2; | ||
64 | } | ||
65 | state[ order ] = tmp1; | ||
66 | C[ order ] += state[ 0 ] * tmp1; | ||
67 | } | ||
68 | |||
69 | /* Copy correlations in silk_float output format */ | ||
70 | for( i = 0; i < order + 1; i++ ) { | ||
71 | corr[ i ] = ( silk_float )C[ i ]; | ||
72 | } | ||
73 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/float/wrappers_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/wrappers_FLP.c new file mode 100644 index 0000000000..ad90b874a4 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/float/wrappers_FLP.c | |||
@@ -0,0 +1,207 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main_FLP.h" | ||
33 | |||
34 | /* Wrappers. Calls flp / fix code */ | ||
35 | |||
36 | /* Convert AR filter coefficients to NLSF parameters */ | ||
37 | void silk_A2NLSF_FLP( | ||
38 | opus_int16 *NLSF_Q15, /* O NLSF vector [ LPC_order ] */ | ||
39 | const silk_float *pAR, /* I LPC coefficients [ LPC_order ] */ | ||
40 | const opus_int LPC_order /* I LPC order */ | ||
41 | ) | ||
42 | { | ||
43 | opus_int i; | ||
44 | opus_int32 a_fix_Q16[ MAX_LPC_ORDER ]; | ||
45 | |||
46 | for( i = 0; i < LPC_order; i++ ) { | ||
47 | a_fix_Q16[ i ] = silk_float2int( pAR[ i ] * 65536.0f ); | ||
48 | } | ||
49 | |||
50 | silk_A2NLSF( NLSF_Q15, a_fix_Q16, LPC_order ); | ||
51 | } | ||
52 | |||
53 | /* Convert LSF parameters to AR prediction filter coefficients */ | ||
54 | void silk_NLSF2A_FLP( | ||
55 | silk_float *pAR, /* O LPC coefficients [ LPC_order ] */ | ||
56 | const opus_int16 *NLSF_Q15, /* I NLSF vector [ LPC_order ] */ | ||
57 | const opus_int LPC_order, /* I LPC order */ | ||
58 | int arch /* I Run-time architecture */ | ||
59 | ) | ||
60 | { | ||
61 | opus_int i; | ||
62 | opus_int16 a_fix_Q12[ MAX_LPC_ORDER ]; | ||
63 | |||
64 | silk_NLSF2A( a_fix_Q12, NLSF_Q15, LPC_order, arch ); | ||
65 | |||
66 | for( i = 0; i < LPC_order; i++ ) { | ||
67 | pAR[ i ] = ( silk_float )a_fix_Q12[ i ] * ( 1.0f / 4096.0f ); | ||
68 | } | ||
69 | } | ||
70 | |||
71 | /******************************************/ | ||
72 | /* Floating-point NLSF processing wrapper */ | ||
73 | /******************************************/ | ||
74 | void silk_process_NLSFs_FLP( | ||
75 | silk_encoder_state *psEncC, /* I/O Encoder state */ | ||
76 | silk_float PredCoef[ 2 ][ MAX_LPC_ORDER ], /* O Prediction coefficients */ | ||
77 | opus_int16 NLSF_Q15[ MAX_LPC_ORDER ], /* I/O Normalized LSFs (quant out) (0 - (2^15-1)) */ | ||
78 | const opus_int16 prev_NLSF_Q15[ MAX_LPC_ORDER ] /* I Previous Normalized LSFs (0 - (2^15-1)) */ | ||
79 | ) | ||
80 | { | ||
81 | opus_int i, j; | ||
82 | opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ]; | ||
83 | |||
84 | silk_process_NLSFs( psEncC, PredCoef_Q12, NLSF_Q15, prev_NLSF_Q15); | ||
85 | |||
86 | for( j = 0; j < 2; j++ ) { | ||
87 | for( i = 0; i < psEncC->predictLPCOrder; i++ ) { | ||
88 | PredCoef[ j ][ i ] = ( silk_float )PredCoef_Q12[ j ][ i ] * ( 1.0f / 4096.0f ); | ||
89 | } | ||
90 | } | ||
91 | } | ||
92 | |||
93 | /****************************************/ | ||
94 | /* Floating-point Silk NSQ wrapper */ | ||
95 | /****************************************/ | ||
96 | void silk_NSQ_wrapper_FLP( | ||
97 | silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ | ||
98 | silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ | ||
99 | SideInfoIndices *psIndices, /* I/O Quantization indices */ | ||
100 | silk_nsq_state *psNSQ, /* I/O Noise Shaping Quantzation state */ | ||
101 | opus_int8 pulses[], /* O Quantized pulse signal */ | ||
102 | const silk_float x[] /* I Prefiltered input signal */ | ||
103 | ) | ||
104 | { | ||
105 | opus_int i, j; | ||
106 | opus_int16 x16[ MAX_FRAME_LENGTH ]; | ||
107 | opus_int32 Gains_Q16[ MAX_NB_SUBFR ]; | ||
108 | silk_DWORD_ALIGN opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ]; | ||
109 | opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ]; | ||
110 | opus_int LTP_scale_Q14; | ||
111 | |||
112 | /* Noise shaping parameters */ | ||
113 | opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ]; | ||
114 | opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ]; /* Packs two int16 coefficients per int32 value */ | ||
115 | opus_int Lambda_Q10; | ||
116 | opus_int Tilt_Q14[ MAX_NB_SUBFR ]; | ||
117 | opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ]; | ||
118 | |||
119 | /* Convert control struct to fix control struct */ | ||
120 | /* Noise shape parameters */ | ||
121 | for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { | ||
122 | for( j = 0; j < psEnc->sCmn.shapingLPCOrder; j++ ) { | ||
123 | AR_Q13[ i * MAX_SHAPE_LPC_ORDER + j ] = silk_float2int( psEncCtrl->AR[ i * MAX_SHAPE_LPC_ORDER + j ] * 8192.0f ); | ||
124 | } | ||
125 | } | ||
126 | |||
127 | for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { | ||
128 | LF_shp_Q14[ i ] = silk_LSHIFT32( silk_float2int( psEncCtrl->LF_AR_shp[ i ] * 16384.0f ), 16 ) | | ||
129 | (opus_uint16)silk_float2int( psEncCtrl->LF_MA_shp[ i ] * 16384.0f ); | ||
130 | Tilt_Q14[ i ] = (opus_int)silk_float2int( psEncCtrl->Tilt[ i ] * 16384.0f ); | ||
131 | HarmShapeGain_Q14[ i ] = (opus_int)silk_float2int( psEncCtrl->HarmShapeGain[ i ] * 16384.0f ); | ||
132 | } | ||
133 | Lambda_Q10 = ( opus_int )silk_float2int( psEncCtrl->Lambda * 1024.0f ); | ||
134 | |||
135 | /* prediction and coding parameters */ | ||
136 | for( i = 0; i < psEnc->sCmn.nb_subfr * LTP_ORDER; i++ ) { | ||
137 | LTPCoef_Q14[ i ] = (opus_int16)silk_float2int( psEncCtrl->LTPCoef[ i ] * 16384.0f ); | ||
138 | } | ||
139 | |||
140 | for( j = 0; j < 2; j++ ) { | ||
141 | for( i = 0; i < psEnc->sCmn.predictLPCOrder; i++ ) { | ||
142 | PredCoef_Q12[ j ][ i ] = (opus_int16)silk_float2int( psEncCtrl->PredCoef[ j ][ i ] * 4096.0f ); | ||
143 | } | ||
144 | } | ||
145 | |||
146 | for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { | ||
147 | Gains_Q16[ i ] = silk_float2int( psEncCtrl->Gains[ i ] * 65536.0f ); | ||
148 | silk_assert( Gains_Q16[ i ] > 0 ); | ||
149 | } | ||
150 | |||
151 | if( psIndices->signalType == TYPE_VOICED ) { | ||
152 | LTP_scale_Q14 = silk_LTPScales_table_Q14[ psIndices->LTP_scaleIndex ]; | ||
153 | } else { | ||
154 | LTP_scale_Q14 = 0; | ||
155 | } | ||
156 | |||
157 | /* Convert input to fix */ | ||
158 | for( i = 0; i < psEnc->sCmn.frame_length; i++ ) { | ||
159 | x16[ i ] = silk_float2int( x[ i ] ); | ||
160 | } | ||
161 | |||
162 | /* Call NSQ */ | ||
163 | if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) { | ||
164 | silk_NSQ_del_dec( &psEnc->sCmn, psNSQ, psIndices, x16, pulses, PredCoef_Q12[ 0 ], LTPCoef_Q14, | ||
165 | AR_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, psEncCtrl->pitchL, Lambda_Q10, LTP_scale_Q14, psEnc->sCmn.arch ); | ||
166 | } else { | ||
167 | silk_NSQ( &psEnc->sCmn, psNSQ, psIndices, x16, pulses, PredCoef_Q12[ 0 ], LTPCoef_Q14, | ||
168 | AR_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, psEncCtrl->pitchL, Lambda_Q10, LTP_scale_Q14, psEnc->sCmn.arch ); | ||
169 | } | ||
170 | } | ||
171 | |||
172 | /***********************************************/ | ||
173 | /* Floating-point Silk LTP quantiation wrapper */ | ||
174 | /***********************************************/ | ||
175 | void silk_quant_LTP_gains_FLP( | ||
176 | silk_float B[ MAX_NB_SUBFR * LTP_ORDER ], /* O Quantized LTP gains */ | ||
177 | opus_int8 cbk_index[ MAX_NB_SUBFR ], /* O Codebook index */ | ||
178 | opus_int8 *periodicity_index, /* O Periodicity index */ | ||
179 | opus_int32 *sum_log_gain_Q7, /* I/O Cumulative max prediction gain */ | ||
180 | silk_float *pred_gain_dB, /* O LTP prediction gain */ | ||
181 | const silk_float XX[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* I Correlation matrix */ | ||
182 | const silk_float xX[ MAX_NB_SUBFR * LTP_ORDER ], /* I Correlation vector */ | ||
183 | const opus_int subfr_len, /* I Number of samples per subframe */ | ||
184 | const opus_int nb_subfr, /* I Number of subframes */ | ||
185 | int arch /* I Run-time architecture */ | ||
186 | ) | ||
187 | { | ||
188 | opus_int i, pred_gain_dB_Q7; | ||
189 | opus_int16 B_Q14[ MAX_NB_SUBFR * LTP_ORDER ]; | ||
190 | opus_int32 XX_Q17[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ]; | ||
191 | opus_int32 xX_Q17[ MAX_NB_SUBFR * LTP_ORDER ]; | ||
192 | |||
193 | for( i = 0; i < nb_subfr * LTP_ORDER * LTP_ORDER; i++ ) { | ||
194 | XX_Q17[ i ] = (opus_int32)silk_float2int( XX[ i ] * 131072.0f ); | ||
195 | } | ||
196 | for( i = 0; i < nb_subfr * LTP_ORDER; i++ ) { | ||
197 | xX_Q17[ i ] = (opus_int32)silk_float2int( xX[ i ] * 131072.0f ); | ||
198 | } | ||
199 | |||
200 | silk_quant_LTP_gains( B_Q14, cbk_index, periodicity_index, sum_log_gain_Q7, &pred_gain_dB_Q7, XX_Q17, xX_Q17, subfr_len, nb_subfr, arch ); | ||
201 | |||
202 | for( i = 0; i < nb_subfr * LTP_ORDER; i++ ) { | ||
203 | B[ i ] = (silk_float)B_Q14[ i ] * ( 1.0f / 16384.0f ); | ||
204 | } | ||
205 | |||
206 | *pred_gain_dB = (silk_float)pred_gain_dB_Q7 * ( 1.0f / 128.0f ); | ||
207 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/gain_quant.c b/lib/rbcodec/codecs/libopus/silk/gain_quant.c index ed084073b1..ee65245aa3 100644 --- a/lib/rbcodec/codecs/libopus/silk/gain_quant.c +++ b/lib/rbcodec/codecs/libopus/silk/gain_quant.c | |||
@@ -35,7 +35,6 @@ POSSIBILITY OF SUCH DAMAGE. | |||
35 | #define SCALE_Q16 ( ( 65536 * ( N_LEVELS_QGAIN - 1 ) ) / ( ( ( MAX_QGAIN_DB - MIN_QGAIN_DB ) * 128 ) / 6 ) ) | 35 | #define SCALE_Q16 ( ( 65536 * ( N_LEVELS_QGAIN - 1 ) ) / ( ( ( MAX_QGAIN_DB - MIN_QGAIN_DB ) * 128 ) / 6 ) ) |
36 | #define INV_SCALE_Q16 ( ( 65536 * ( ( ( MAX_QGAIN_DB - MIN_QGAIN_DB ) * 128 ) / 6 ) ) / ( N_LEVELS_QGAIN - 1 ) ) | 36 | #define INV_SCALE_Q16 ( ( 65536 * ( ( ( MAX_QGAIN_DB - MIN_QGAIN_DB ) * 128 ) / 6 ) ) / ( N_LEVELS_QGAIN - 1 ) ) |
37 | 37 | ||
38 | #if 0 | ||
39 | /* Gain scalar quantization with hysteresis, uniform on log scale */ | 38 | /* Gain scalar quantization with hysteresis, uniform on log scale */ |
40 | void silk_gains_quant( | 39 | void silk_gains_quant( |
41 | opus_int8 ind[ MAX_NB_SUBFR ], /* O gain indices */ | 40 | opus_int8 ind[ MAX_NB_SUBFR ], /* O gain indices */ |
@@ -77,6 +76,7 @@ void silk_gains_quant( | |||
77 | /* Accumulate deltas */ | 76 | /* Accumulate deltas */ |
78 | if( ind[ k ] > double_step_size_threshold ) { | 77 | if( ind[ k ] > double_step_size_threshold ) { |
79 | *prev_ind += silk_LSHIFT( ind[ k ], 1 ) - double_step_size_threshold; | 78 | *prev_ind += silk_LSHIFT( ind[ k ], 1 ) - double_step_size_threshold; |
79 | *prev_ind = silk_min_int( *prev_ind, N_LEVELS_QGAIN - 1 ); | ||
80 | } else { | 80 | } else { |
81 | *prev_ind += ind[ k ]; | 81 | *prev_ind += ind[ k ]; |
82 | } | 82 | } |
@@ -89,7 +89,6 @@ void silk_gains_quant( | |||
89 | gain_Q16[ k ] = silk_log2lin( silk_min_32( silk_SMULWB( INV_SCALE_Q16, *prev_ind ) + OFFSET, 3967 ) ); /* 3967 = 31 in Q7 */ | 89 | gain_Q16[ k ] = silk_log2lin( silk_min_32( silk_SMULWB( INV_SCALE_Q16, *prev_ind ) + OFFSET, 3967 ) ); /* 3967 = 31 in Q7 */ |
90 | } | 90 | } |
91 | } | 91 | } |
92 | #endif | ||
93 | 92 | ||
94 | /* Gains scalar dequantization, uniform on log scale */ | 93 | /* Gains scalar dequantization, uniform on log scale */ |
95 | void silk_gains_dequant( | 94 | void silk_gains_dequant( |
@@ -125,7 +124,6 @@ void silk_gains_dequant( | |||
125 | } | 124 | } |
126 | } | 125 | } |
127 | 126 | ||
128 | #if 0 | ||
129 | /* Compute unique identifier of gain indices vector */ | 127 | /* Compute unique identifier of gain indices vector */ |
130 | opus_int32 silk_gains_ID( /* O returns unique identifier of gains */ | 128 | opus_int32 silk_gains_ID( /* O returns unique identifier of gains */ |
131 | const opus_int8 ind[ MAX_NB_SUBFR ], /* I gain indices */ | 129 | const opus_int8 ind[ MAX_NB_SUBFR ], /* I gain indices */ |
@@ -142,4 +140,3 @@ opus_int32 silk_gains_ID( /* O returns | |||
142 | 140 | ||
143 | return gainsID; | 141 | return gainsID; |
144 | } | 142 | } |
145 | #endif | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/init_decoder.c b/lib/rbcodec/codecs/libopus/silk/init_decoder.c index f887c67886..16c03dcd1c 100644 --- a/lib/rbcodec/codecs/libopus/silk/init_decoder.c +++ b/lib/rbcodec/codecs/libopus/silk/init_decoder.c | |||
@@ -44,6 +44,7 @@ opus_int silk_init_decoder( | |||
44 | /* Used to deactivate LSF interpolation */ | 44 | /* Used to deactivate LSF interpolation */ |
45 | psDec->first_frame_after_reset = 1; | 45 | psDec->first_frame_after_reset = 1; |
46 | psDec->prev_gain_Q16 = 65536; | 46 | psDec->prev_gain_Q16 = 65536; |
47 | psDec->arch = opus_select_arch(); | ||
47 | 48 | ||
48 | /* Reset CNG state */ | 49 | /* Reset CNG state */ |
49 | silk_CNG_Reset( psDec ); | 50 | silk_CNG_Reset( psDec ); |
diff --git a/lib/rbcodec/codecs/libopus/silk/init_encoder.c b/lib/rbcodec/codecs/libopus/silk/init_encoder.c new file mode 100644 index 0000000000..65995c33fa --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/init_encoder.c | |||
@@ -0,0 +1,64 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | #ifdef FIXED_POINT | ||
32 | #include "main_FIX.h" | ||
33 | #else | ||
34 | #include "main_FLP.h" | ||
35 | #endif | ||
36 | #include "tuning_parameters.h" | ||
37 | #include "cpu_support.h" | ||
38 | |||
39 | /*********************************/ | ||
40 | /* Initialize Silk Encoder state */ | ||
41 | /*********************************/ | ||
42 | opus_int silk_init_encoder( | ||
43 | silk_encoder_state_Fxx *psEnc, /* I/O Pointer to Silk FIX encoder state */ | ||
44 | int arch /* I Run-time architecture */ | ||
45 | ) | ||
46 | { | ||
47 | opus_int ret = 0; | ||
48 | |||
49 | /* Clear the entire encoder state */ | ||
50 | silk_memset( psEnc, 0, sizeof( silk_encoder_state_Fxx ) ); | ||
51 | |||
52 | psEnc->sCmn.arch = arch; | ||
53 | |||
54 | psEnc->sCmn.variable_HP_smth1_Q15 = silk_LSHIFT( silk_lin2log( SILK_FIX_CONST( VARIABLE_HP_MIN_CUTOFF_HZ, 16 ) ) - ( 16 << 7 ), 8 ); | ||
55 | psEnc->sCmn.variable_HP_smth2_Q15 = psEnc->sCmn.variable_HP_smth1_Q15; | ||
56 | |||
57 | /* Used to deactivate LSF interpolation, pitch prediction */ | ||
58 | psEnc->sCmn.first_frame_after_reset = 1; | ||
59 | |||
60 | /* Initialize Silk VAD */ | ||
61 | ret += silk_VAD_Init( &psEnc->sCmn.sVAD ); | ||
62 | |||
63 | return ret; | ||
64 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/inner_prod_aligned.c b/lib/rbcodec/codecs/libopus/silk/inner_prod_aligned.c new file mode 100644 index 0000000000..257ae9e04e --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/inner_prod_aligned.c | |||
@@ -0,0 +1,47 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "SigProc_FIX.h" | ||
33 | |||
34 | opus_int32 silk_inner_prod_aligned_scale( | ||
35 | const opus_int16 *const inVec1, /* I input vector 1 */ | ||
36 | const opus_int16 *const inVec2, /* I input vector 2 */ | ||
37 | const opus_int scale, /* I number of bits to shift */ | ||
38 | const opus_int len /* I vector lengths */ | ||
39 | ) | ||
40 | { | ||
41 | opus_int i; | ||
42 | opus_int32 sum = 0; | ||
43 | for( i = 0; i < len; i++ ) { | ||
44 | sum = silk_ADD_RSHIFT32( sum, silk_SMULBB( inVec1[ i ], inVec2[ i ] ), scale ); | ||
45 | } | ||
46 | return sum; | ||
47 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/interpolate.c b/lib/rbcodec/codecs/libopus/silk/interpolate.c new file mode 100644 index 0000000000..833c28ef8e --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/interpolate.c | |||
@@ -0,0 +1,51 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main.h" | ||
33 | |||
34 | /* Interpolate two vectors */ | ||
35 | void silk_interpolate( | ||
36 | opus_int16 xi[ MAX_LPC_ORDER ], /* O interpolated vector */ | ||
37 | const opus_int16 x0[ MAX_LPC_ORDER ], /* I first vector */ | ||
38 | const opus_int16 x1[ MAX_LPC_ORDER ], /* I second vector */ | ||
39 | const opus_int ifact_Q2, /* I interp. factor, weight on 2nd vector */ | ||
40 | const opus_int d /* I number of parameters */ | ||
41 | ) | ||
42 | { | ||
43 | opus_int i; | ||
44 | |||
45 | celt_assert( ifact_Q2 >= 0 ); | ||
46 | celt_assert( ifact_Q2 <= 4 ); | ||
47 | |||
48 | for( i = 0; i < d; i++ ) { | ||
49 | xi[ i ] = (opus_int16)silk_ADD_RSHIFT( x0[ i ], silk_SMULBB( x1[ i ] - x0[ i ], ifact_Q2 ), 2 ); | ||
50 | } | ||
51 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/lin2log.c b/lib/rbcodec/codecs/libopus/silk/lin2log.c new file mode 100644 index 0000000000..0d5155aa86 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/lin2log.c | |||
@@ -0,0 +1,46 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "SigProc_FIX.h" | ||
33 | /* Approximation of 128 * log2() (very close inverse of silk_log2lin()) */ | ||
34 | /* Convert input to a log scale */ | ||
35 | opus_int32 silk_lin2log( | ||
36 | const opus_int32 inLin /* I input in linear scale */ | ||
37 | ) | ||
38 | { | ||
39 | opus_int32 lz, frac_Q7; | ||
40 | |||
41 | silk_CLZ_FRAC( inLin, &lz, &frac_Q7 ); | ||
42 | |||
43 | /* Piece-wise parabolic approximation */ | ||
44 | return silk_ADD_LSHIFT32( silk_SMLAWB( frac_Q7, silk_MUL( frac_Q7, 128 - frac_Q7 ), 179 ), 31 - lz, 7 ); | ||
45 | } | ||
46 | |||
diff --git a/lib/rbcodec/codecs/libopus/silk/log2lin.c b/lib/rbcodec/codecs/libopus/silk/log2lin.c index a692e009db..b7c48e4740 100644 --- a/lib/rbcodec/codecs/libopus/silk/log2lin.c +++ b/lib/rbcodec/codecs/libopus/silk/log2lin.c | |||
@@ -33,7 +33,7 @@ POSSIBILITY OF SUCH DAMAGE. | |||
33 | 33 | ||
34 | /* Approximation of 2^() (very close inverse of silk_lin2log()) */ | 34 | /* Approximation of 2^() (very close inverse of silk_lin2log()) */ |
35 | /* Convert input to a linear scale */ | 35 | /* Convert input to a linear scale */ |
36 | opus_int32 silk_log2lin( | 36 | opus_int32 silk_log2lin( |
37 | const opus_int32 inLog_Q7 /* I input on log scale */ | 37 | const opus_int32 inLog_Q7 /* I input on log scale */ |
38 | ) | 38 | ) |
39 | { | 39 | { |
@@ -42,8 +42,8 @@ opus_int32 silk_log2lin( | |||
42 | if( inLog_Q7 < 0 ) { | 42 | if( inLog_Q7 < 0 ) { |
43 | return 0; | 43 | return 0; |
44 | } else if ( inLog_Q7 >= 3967 ) { | 44 | } else if ( inLog_Q7 >= 3967 ) { |
45 | return silk_int32_MAX; | 45 | return silk_int32_MAX; |
46 | } | 46 | } |
47 | 47 | ||
48 | out = silk_LSHIFT( 1, silk_RSHIFT( inLog_Q7, 7 ) ); | 48 | out = silk_LSHIFT( 1, silk_RSHIFT( inLog_Q7, 7 ) ); |
49 | frac_Q7 = inLog_Q7 & 0x7F; | 49 | frac_Q7 = inLog_Q7 & 0x7F; |
diff --git a/lib/rbcodec/codecs/libopus/silk/macros.h b/lib/rbcodec/codecs/libopus/silk/macros.h index 05623b5df8..3c67b6e5d9 100644 --- a/lib/rbcodec/codecs/libopus/silk/macros.h +++ b/lib/rbcodec/codecs/libopus/silk/macros.h | |||
@@ -34,20 +34,37 @@ POSSIBILITY OF SUCH DAMAGE. | |||
34 | 34 | ||
35 | #include "opus_types.h" | 35 | #include "opus_types.h" |
36 | #include "opus_defines.h" | 36 | #include "opus_defines.h" |
37 | #include "arch.h" | ||
37 | 38 | ||
38 | /* This is an OPUS_INLINE header file for general platform. */ | 39 | /* This is an OPUS_INLINE header file for general platform. */ |
39 | 40 | ||
40 | /* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */ | 41 | /* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */ |
42 | #if OPUS_FAST_INT64 | ||
43 | #define silk_SMULWB(a32, b32) ((opus_int32)(((a32) * (opus_int64)((opus_int16)(b32))) >> 16)) | ||
44 | #else | ||
41 | #define silk_SMULWB(a32, b32) ((((a32) >> 16) * (opus_int32)((opus_int16)(b32))) + ((((a32) & 0x0000FFFF) * (opus_int32)((opus_int16)(b32))) >> 16)) | 45 | #define silk_SMULWB(a32, b32) ((((a32) >> 16) * (opus_int32)((opus_int16)(b32))) + ((((a32) & 0x0000FFFF) * (opus_int32)((opus_int16)(b32))) >> 16)) |
46 | #endif | ||
42 | 47 | ||
43 | /* a32 + (b32 * (opus_int32)((opus_int16)(c32))) >> 16 output have to be 32bit int */ | 48 | /* a32 + (b32 * (opus_int32)((opus_int16)(c32))) >> 16 output have to be 32bit int */ |
49 | #if OPUS_FAST_INT64 | ||
50 | #define silk_SMLAWB(a32, b32, c32) ((opus_int32)((a32) + (((b32) * (opus_int64)((opus_int16)(c32))) >> 16))) | ||
51 | #else | ||
44 | #define silk_SMLAWB(a32, b32, c32) ((a32) + ((((b32) >> 16) * (opus_int32)((opus_int16)(c32))) + ((((b32) & 0x0000FFFF) * (opus_int32)((opus_int16)(c32))) >> 16))) | 52 | #define silk_SMLAWB(a32, b32, c32) ((a32) + ((((b32) >> 16) * (opus_int32)((opus_int16)(c32))) + ((((b32) & 0x0000FFFF) * (opus_int32)((opus_int16)(c32))) >> 16))) |
53 | #endif | ||
45 | 54 | ||
46 | /* (a32 * (b32 >> 16)) >> 16 */ | 55 | /* (a32 * (b32 >> 16)) >> 16 */ |
56 | #if OPUS_FAST_INT64 | ||
57 | #define silk_SMULWT(a32, b32) ((opus_int32)(((a32) * (opus_int64)((b32) >> 16)) >> 16)) | ||
58 | #else | ||
47 | #define silk_SMULWT(a32, b32) (((a32) >> 16) * ((b32) >> 16) + ((((a32) & 0x0000FFFF) * ((b32) >> 16)) >> 16)) | 59 | #define silk_SMULWT(a32, b32) (((a32) >> 16) * ((b32) >> 16) + ((((a32) & 0x0000FFFF) * ((b32) >> 16)) >> 16)) |
60 | #endif | ||
48 | 61 | ||
49 | /* a32 + (b32 * (c32 >> 16)) >> 16 */ | 62 | /* a32 + (b32 * (c32 >> 16)) >> 16 */ |
63 | #if OPUS_FAST_INT64 | ||
64 | #define silk_SMLAWT(a32, b32, c32) ((opus_int32)((a32) + (((b32) * ((opus_int64)(c32) >> 16)) >> 16))) | ||
65 | #else | ||
50 | #define silk_SMLAWT(a32, b32, c32) ((a32) + (((b32) >> 16) * ((c32) >> 16)) + ((((b32) & 0x0000FFFF) * ((c32) >> 16)) >> 16)) | 66 | #define silk_SMLAWT(a32, b32, c32) ((a32) + (((b32) >> 16) * ((c32) >> 16)) + ((((b32) & 0x0000FFFF) * ((c32) >> 16)) >> 16)) |
67 | #endif | ||
51 | 68 | ||
52 | /* (opus_int32)((opus_int16)(a3))) * (opus_int32)((opus_int16)(b32)) output have to be 32bit int */ | 69 | /* (opus_int32)((opus_int16)(a3))) * (opus_int32)((opus_int16)(b32)) output have to be 32bit int */ |
53 | #define silk_SMULBB(a32, b32) ((opus_int32)((opus_int16)(a32)) * (opus_int32)((opus_int16)(b32))) | 70 | #define silk_SMULBB(a32, b32) ((opus_int32)((opus_int16)(a32)) * (opus_int32)((opus_int16)(b32))) |
@@ -65,10 +82,18 @@ POSSIBILITY OF SUCH DAMAGE. | |||
65 | #define silk_SMLAL(a64, b32, c32) (silk_ADD64((a64), ((opus_int64)(b32) * (opus_int64)(c32)))) | 82 | #define silk_SMLAL(a64, b32, c32) (silk_ADD64((a64), ((opus_int64)(b32) * (opus_int64)(c32)))) |
66 | 83 | ||
67 | /* (a32 * b32) >> 16 */ | 84 | /* (a32 * b32) >> 16 */ |
85 | #if OPUS_FAST_INT64 | ||
86 | #define silk_SMULWW(a32, b32) ((opus_int32)(((opus_int64)(a32) * (b32)) >> 16)) | ||
87 | #else | ||
68 | #define silk_SMULWW(a32, b32) silk_MLA(silk_SMULWB((a32), (b32)), (a32), silk_RSHIFT_ROUND((b32), 16)) | 88 | #define silk_SMULWW(a32, b32) silk_MLA(silk_SMULWB((a32), (b32)), (a32), silk_RSHIFT_ROUND((b32), 16)) |
89 | #endif | ||
69 | 90 | ||
70 | /* a32 + ((b32 * c32) >> 16) */ | 91 | /* a32 + ((b32 * c32) >> 16) */ |
92 | #if OPUS_FAST_INT64 | ||
93 | #define silk_SMLAWW(a32, b32, c32) ((opus_int32)((a32) + (((opus_int64)(b32) * (c32)) >> 16))) | ||
94 | #else | ||
71 | #define silk_SMLAWW(a32, b32, c32) silk_MLA(silk_SMLAWB((a32), (b32), (c32)), (b32), silk_RSHIFT_ROUND((c32), 16)) | 95 | #define silk_SMLAWW(a32, b32, c32) silk_MLA(silk_SMLAWB((a32), (b32), (c32)), (b32), silk_RSHIFT_ROUND((c32), 16)) |
96 | #endif | ||
72 | 97 | ||
73 | /* add/subtract with output saturated */ | 98 | /* add/subtract with output saturated */ |
74 | #define silk_ADD_SAT32(a, b) ((((opus_uint32)(a) + (opus_uint32)(b)) & 0x80000000) == 0 ? \ | 99 | #define silk_ADD_SAT32(a, b) ((((opus_uint32)(a) + (opus_uint32)(b)) & 0x80000000) == 0 ? \ |
@@ -118,8 +143,8 @@ static OPUS_INLINE opus_int32 silk_CLZ32(opus_int32 in32) | |||
118 | #include "arm/macros_armv5e.h" | 143 | #include "arm/macros_armv5e.h" |
119 | #endif | 144 | #endif |
120 | 145 | ||
121 | #ifdef OPUS_CF_INLINE_ASM | 146 | #ifdef OPUS_ARM_PRESUME_AARCH64_NEON_INTR |
122 | #include "cf/macros_cf.h" | 147 | #include "arm/macros_arm64.h" |
123 | #endif | 148 | #endif |
124 | 149 | ||
125 | #endif /* SILK_MACROS_H */ | 150 | #endif /* SILK_MACROS_H */ |
diff --git a/lib/rbcodec/codecs/libopus/silk/main.h b/lib/rbcodec/codecs/libopus/silk/main.h index 77524f5b57..1a33eed549 100644 --- a/lib/rbcodec/codecs/libopus/silk/main.h +++ b/lib/rbcodec/codecs/libopus/silk/main.h | |||
@@ -38,6 +38,14 @@ POSSIBILITY OF SUCH DAMAGE. | |||
38 | #include "entenc.h" | 38 | #include "entenc.h" |
39 | #include "entdec.h" | 39 | #include "entdec.h" |
40 | 40 | ||
41 | #if defined(OPUS_X86_MAY_HAVE_SSE4_1) | ||
42 | #include "x86/main_sse.h" | ||
43 | #endif | ||
44 | |||
45 | #if (defined(OPUS_ARM_ASM) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)) | ||
46 | #include "arm/NSQ_del_dec_arm.h" | ||
47 | #endif | ||
48 | |||
41 | /* Convert Left/Right stereo signal to adaptive Mid/Side representation */ | 49 | /* Convert Left/Right stereo signal to adaptive Mid/Side representation */ |
42 | void silk_stereo_LR_to_MS( | 50 | void silk_stereo_LR_to_MS( |
43 | stereo_enc_state *state, /* I/O State */ | 51 | stereo_enc_state *state, /* I/O State */ |
@@ -105,22 +113,22 @@ void silk_stereo_decode_mid_only( | |||
105 | 113 | ||
106 | /* Encodes signs of excitation */ | 114 | /* Encodes signs of excitation */ |
107 | void silk_encode_signs( | 115 | void silk_encode_signs( |
108 | ec_enc *psRangeEnc, /* I/O Compressor data structure */ | 116 | ec_enc *psRangeEnc, /* I/O Compressor data structure */ |
109 | const opus_int8 pulses[], /* I pulse signal */ | 117 | const opus_int8 pulses[], /* I pulse signal */ |
110 | opus_int length, /* I length of input */ | 118 | opus_int length, /* I length of input */ |
111 | const opus_int signalType, /* I Signal type */ | 119 | const opus_int signalType, /* I Signal type */ |
112 | const opus_int quantOffsetType, /* I Quantization offset type */ | 120 | const opus_int quantOffsetType, /* I Quantization offset type */ |
113 | const opus_int sum_pulses[ MAX_NB_SHELL_BLOCKS ] /* I Sum of absolute pulses per block */ | 121 | const opus_int sum_pulses[ MAX_NB_SHELL_BLOCKS ] /* I Sum of absolute pulses per block */ |
114 | ); | 122 | ); |
115 | 123 | ||
116 | /* Decodes signs of excitation */ | 124 | /* Decodes signs of excitation */ |
117 | void silk_decode_signs( | 125 | void silk_decode_signs( |
118 | ec_dec *psRangeDec, /* I/O Compressor data structure */ | 126 | ec_dec *psRangeDec, /* I/O Compressor data structure */ |
119 | opus_int16 pulses[], /* I/O pulse signal */ | 127 | opus_int16 pulses[], /* I/O pulse signal */ |
120 | opus_int length, /* I length of input */ | 128 | opus_int length, /* I length of input */ |
121 | const opus_int signalType, /* I Signal type */ | 129 | const opus_int signalType, /* I Signal type */ |
122 | const opus_int quantOffsetType, /* I Quantization offset type */ | 130 | const opus_int quantOffsetType, /* I Quantization offset type */ |
123 | const opus_int sum_pulses[ MAX_NB_SHELL_BLOCKS ] /* I Sum of absolute pulses per block */ | 131 | const opus_int sum_pulses[ MAX_NB_SHELL_BLOCKS ] /* I Sum of absolute pulses per block */ |
124 | ); | 132 | ); |
125 | 133 | ||
126 | /* Check encoder control struct */ | 134 | /* Check encoder control struct */ |
@@ -201,43 +209,52 @@ void silk_interpolate( | |||
201 | 209 | ||
202 | /* LTP tap quantizer */ | 210 | /* LTP tap quantizer */ |
203 | void silk_quant_LTP_gains( | 211 | void silk_quant_LTP_gains( |
204 | opus_int16 B_Q14[ MAX_NB_SUBFR * LTP_ORDER ], /* I/O (un)quantized LTP gains */ | 212 | opus_int16 B_Q14[ MAX_NB_SUBFR * LTP_ORDER ], /* O Quantized LTP gains */ |
205 | opus_int8 cbk_index[ MAX_NB_SUBFR ], /* O Codebook Index */ | 213 | opus_int8 cbk_index[ MAX_NB_SUBFR ], /* O Codebook Index */ |
206 | opus_int8 *periodicity_index, /* O Periodicity Index */ | 214 | opus_int8 *periodicity_index, /* O Periodicity Index */ |
207 | opus_int32 *sum_gain_dB_Q7, /* I/O Cumulative max prediction gain */ | 215 | opus_int32 *sum_gain_dB_Q7, /* I/O Cumulative max prediction gain */ |
208 | const opus_int32 W_Q18[ MAX_NB_SUBFR*LTP_ORDER*LTP_ORDER ], /* I Error Weights in Q18 */ | 216 | opus_int *pred_gain_dB_Q7, /* O LTP prediction gain */ |
209 | opus_int mu_Q9, /* I Mu value (R/D tradeoff) */ | 217 | const opus_int32 XX_Q17[ MAX_NB_SUBFR*LTP_ORDER*LTP_ORDER ], /* I Correlation matrix in Q18 */ |
210 | opus_int lowComplexity, /* I Flag for low complexity */ | 218 | const opus_int32 xX_Q17[ MAX_NB_SUBFR*LTP_ORDER ], /* I Correlation vector in Q18 */ |
211 | const opus_int nb_subfr /* I number of subframes */ | 219 | const opus_int subfr_len, /* I Number of samples per subframe */ |
220 | const opus_int nb_subfr, /* I Number of subframes */ | ||
221 | int arch /* I Run-time architecture */ | ||
212 | ); | 222 | ); |
213 | 223 | ||
214 | /* Entropy constrained matrix-weighted VQ, for a single input data vector */ | 224 | /* Entropy constrained matrix-weighted VQ, for a single input data vector */ |
215 | void silk_VQ_WMat_EC( | 225 | void silk_VQ_WMat_EC_c( |
216 | opus_int8 *ind, /* O index of best codebook vector */ | 226 | opus_int8 *ind, /* O index of best codebook vector */ |
217 | opus_int32 *rate_dist_Q14, /* O best weighted quant error + mu * rate */ | 227 | opus_int32 *res_nrg_Q15, /* O best residual energy */ |
228 | opus_int32 *rate_dist_Q8, /* O best total bitrate */ | ||
218 | opus_int *gain_Q7, /* O sum of absolute LTP coefficients */ | 229 | opus_int *gain_Q7, /* O sum of absolute LTP coefficients */ |
219 | const opus_int16 *in_Q14, /* I input vector to be quantized */ | 230 | const opus_int32 *XX_Q17, /* I correlation matrix */ |
220 | const opus_int32 *W_Q18, /* I weighting matrix */ | 231 | const opus_int32 *xX_Q17, /* I correlation vector */ |
221 | const opus_int8 *cb_Q7, /* I codebook */ | 232 | const opus_int8 *cb_Q7, /* I codebook */ |
222 | const opus_uint8 *cb_gain_Q7, /* I codebook effective gain */ | 233 | const opus_uint8 *cb_gain_Q7, /* I codebook effective gain */ |
223 | const opus_uint8 *cl_Q5, /* I code length for each codebook vector */ | 234 | const opus_uint8 *cl_Q5, /* I code length for each codebook vector */ |
224 | const opus_int mu_Q9, /* I tradeoff betw. weighted error and rate */ | 235 | const opus_int subfr_len, /* I number of samples per subframe */ |
225 | const opus_int32 max_gain_Q7, /* I maximum sum of absolute LTP coefficients */ | 236 | const opus_int32 max_gain_Q7, /* I maximum sum of absolute LTP coefficients */ |
226 | opus_int L /* I number of vectors in codebook */ | 237 | const opus_int L /* I number of vectors in codebook */ |
227 | ); | 238 | ); |
228 | 239 | ||
240 | #if !defined(OVERRIDE_silk_VQ_WMat_EC) | ||
241 | #define silk_VQ_WMat_EC(ind, res_nrg_Q15, rate_dist_Q8, gain_Q7, XX_Q17, xX_Q17, cb_Q7, cb_gain_Q7, cl_Q5, subfr_len, max_gain_Q7, L, arch) \ | ||
242 | ((void)(arch),silk_VQ_WMat_EC_c(ind, res_nrg_Q15, rate_dist_Q8, gain_Q7, XX_Q17, xX_Q17, cb_Q7, cb_gain_Q7, cl_Q5, subfr_len, max_gain_Q7, L)) | ||
243 | #endif | ||
244 | |||
229 | /************************************/ | 245 | /************************************/ |
230 | /* Noise shaping quantization (NSQ) */ | 246 | /* Noise shaping quantization (NSQ) */ |
231 | /************************************/ | 247 | /************************************/ |
232 | void silk_NSQ( | 248 | |
233 | const silk_encoder_state *psEncC, /* I/O Encoder State */ | 249 | void silk_NSQ_c( |
250 | const silk_encoder_state *psEncC, /* I Encoder State */ | ||
234 | silk_nsq_state *NSQ, /* I/O NSQ state */ | 251 | silk_nsq_state *NSQ, /* I/O NSQ state */ |
235 | SideInfoIndices *psIndices, /* I/O Quantization Indices */ | 252 | SideInfoIndices *psIndices, /* I/O Quantization Indices */ |
236 | const opus_int32 x_Q3[], /* I Prefiltered input signal */ | 253 | const opus_int16 x16[], /* I Input */ |
237 | opus_int8 pulses[], /* O Quantized pulse signal */ | 254 | opus_int8 pulses[], /* O Quantized pulse signal */ |
238 | const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ | 255 | const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ |
239 | const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ | 256 | const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ |
240 | const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ | 257 | const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ |
241 | const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ | 258 | const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ |
242 | const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ | 259 | const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ |
243 | const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ | 260 | const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ |
@@ -247,16 +264,23 @@ void silk_NSQ( | |||
247 | const opus_int LTP_scale_Q14 /* I LTP state scaling */ | 264 | const opus_int LTP_scale_Q14 /* I LTP state scaling */ |
248 | ); | 265 | ); |
249 | 266 | ||
267 | #if !defined(OVERRIDE_silk_NSQ) | ||
268 | #define silk_NSQ(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, AR_Q13, \ | ||
269 | HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \ | ||
270 | ((void)(arch),silk_NSQ_c(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, AR_Q13, \ | ||
271 | HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14)) | ||
272 | #endif | ||
273 | |||
250 | /* Noise shaping using delayed decision */ | 274 | /* Noise shaping using delayed decision */ |
251 | void silk_NSQ_del_dec( | 275 | void silk_NSQ_del_dec_c( |
252 | const silk_encoder_state *psEncC, /* I/O Encoder State */ | 276 | const silk_encoder_state *psEncC, /* I Encoder State */ |
253 | silk_nsq_state *NSQ, /* I/O NSQ state */ | 277 | silk_nsq_state *NSQ, /* I/O NSQ state */ |
254 | SideInfoIndices *psIndices, /* I/O Quantization Indices */ | 278 | SideInfoIndices *psIndices, /* I/O Quantization Indices */ |
255 | const opus_int32 x_Q3[], /* I Prefiltered input signal */ | 279 | const opus_int16 x16[], /* I Input */ |
256 | opus_int8 pulses[], /* O Quantized pulse signal */ | 280 | opus_int8 pulses[], /* O Quantized pulse signal */ |
257 | const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ | 281 | const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ |
258 | const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ | 282 | const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ |
259 | const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ | 283 | const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ |
260 | const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ | 284 | const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ |
261 | const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ | 285 | const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ |
262 | const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ | 286 | const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ |
@@ -266,6 +290,13 @@ void silk_NSQ_del_dec( | |||
266 | const opus_int LTP_scale_Q14 /* I LTP state scaling */ | 290 | const opus_int LTP_scale_Q14 /* I LTP state scaling */ |
267 | ); | 291 | ); |
268 | 292 | ||
293 | #if !defined(OVERRIDE_silk_NSQ_del_dec) | ||
294 | #define silk_NSQ_del_dec(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, AR_Q13, \ | ||
295 | HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \ | ||
296 | ((void)(arch),silk_NSQ_del_dec_c(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, AR_Q13, \ | ||
297 | HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14)) | ||
298 | #endif | ||
299 | |||
269 | /************/ | 300 | /************/ |
270 | /* Silk VAD */ | 301 | /* Silk VAD */ |
271 | /************/ | 302 | /************/ |
@@ -275,11 +306,15 @@ opus_int silk_VAD_Init( /* O Return v | |||
275 | ); | 306 | ); |
276 | 307 | ||
277 | /* Get speech activity level in Q8 */ | 308 | /* Get speech activity level in Q8 */ |
278 | opus_int silk_VAD_GetSA_Q8( /* O Return value, 0 if success */ | 309 | opus_int silk_VAD_GetSA_Q8_c( /* O Return value, 0 if success */ |
279 | silk_encoder_state *psEncC, /* I/O Encoder state */ | 310 | silk_encoder_state *psEncC, /* I/O Encoder state */ |
280 | const opus_int16 pIn[] /* I PCM input */ | 311 | const opus_int16 pIn[] /* I PCM input */ |
281 | ); | 312 | ); |
282 | 313 | ||
314 | #if !defined(OVERRIDE_silk_VAD_GetSA_Q8) | ||
315 | #define silk_VAD_GetSA_Q8(psEnC, pIn, arch) ((void)(arch),silk_VAD_GetSA_Q8_c(psEnC, pIn)) | ||
316 | #endif | ||
317 | |||
283 | /* Low-pass filter with variable cutoff frequency based on */ | 318 | /* Low-pass filter with variable cutoff frequency based on */ |
284 | /* piece-wise linear interpolation between elliptic filters */ | 319 | /* piece-wise linear interpolation between elliptic filters */ |
285 | /* Start by setting transition_frame_no = 1; */ | 320 | /* Start by setting transition_frame_no = 1; */ |
@@ -315,6 +350,7 @@ void silk_NLSF_VQ( | |||
315 | opus_int32 err_Q26[], /* O Quantization errors [K] */ | 350 | opus_int32 err_Q26[], /* O Quantization errors [K] */ |
316 | const opus_int16 in_Q15[], /* I Input vectors to be quantized [LPC_order] */ | 351 | const opus_int16 in_Q15[], /* I Input vectors to be quantized [LPC_order] */ |
317 | const opus_uint8 pCB_Q8[], /* I Codebook vectors [K*LPC_order] */ | 352 | const opus_uint8 pCB_Q8[], /* I Codebook vectors [K*LPC_order] */ |
353 | const opus_int16 pWght_Q9[], /* I Codebook weights [K*LPC_order] */ | ||
318 | const opus_int K, /* I Number of codebook vectors */ | 354 | const opus_int K, /* I Number of codebook vectors */ |
319 | const opus_int LPC_order /* I Number of LPCs */ | 355 | const opus_int LPC_order /* I Number of LPCs */ |
320 | ); | 356 | ); |
@@ -373,7 +409,8 @@ opus_int silk_decode_frame( | |||
373 | opus_int16 pOut[], /* O Pointer to output speech frame */ | 409 | opus_int16 pOut[], /* O Pointer to output speech frame */ |
374 | opus_int32 *pN, /* O Pointer to size of output frame */ | 410 | opus_int32 *pN, /* O Pointer to size of output frame */ |
375 | opus_int lostFlag, /* I 0: no loss, 1 loss, 2 decode fec */ | 411 | opus_int lostFlag, /* I 0: no loss, 1 loss, 2 decode fec */ |
376 | opus_int condCoding /* I The type of conditional coding to use */ | 412 | opus_int condCoding, /* I The type of conditional coding to use */ |
413 | int arch /* I Run-time architecture */ | ||
377 | ); | 414 | ); |
378 | 415 | ||
379 | /* Decode indices from bitstream */ | 416 | /* Decode indices from bitstream */ |
@@ -397,7 +434,8 @@ void silk_decode_core( | |||
397 | silk_decoder_state *psDec, /* I/O Decoder state */ | 434 | silk_decoder_state *psDec, /* I/O Decoder state */ |
398 | silk_decoder_control *psDecCtrl, /* I Decoder control */ | 435 | silk_decoder_control *psDecCtrl, /* I Decoder control */ |
399 | opus_int16 xq[], /* O Decoded speech */ | 436 | opus_int16 xq[], /* O Decoded speech */ |
400 | const opus_int16 pulses[ MAX_FRAME_LENGTH ] /* I Pulse signal */ | 437 | const opus_int16 pulses[ MAX_FRAME_LENGTH ], /* I Pulse signal */ |
438 | int arch /* I Run-time architecture */ | ||
401 | ); | 439 | ); |
402 | 440 | ||
403 | /* Decode quantization indices of excitation (Shell coding) */ | 441 | /* Decode quantization indices of excitation (Shell coding) */ |
diff --git a/lib/rbcodec/codecs/libopus/silk/mips/NSQ_del_dec_mipsr1.h b/lib/rbcodec/codecs/libopus/silk/mips/NSQ_del_dec_mipsr1.h new file mode 100644 index 0000000000..cd70713a8f --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/mips/NSQ_del_dec_mipsr1.h | |||
@@ -0,0 +1,410 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifndef __NSQ_DEL_DEC_MIPSR1_H__ | ||
29 | #define __NSQ_DEL_DEC_MIPSR1_H__ | ||
30 | |||
31 | #ifdef HAVE_CONFIG_H | ||
32 | #include "config.h" | ||
33 | #endif | ||
34 | |||
35 | #include "main.h" | ||
36 | #include "stack_alloc.h" | ||
37 | |||
38 | #define OVERRIDE_silk_noise_shape_quantizer_del_dec | ||
39 | static inline void silk_noise_shape_quantizer_del_dec( | ||
40 | silk_nsq_state *NSQ, /* I/O NSQ state */ | ||
41 | NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ | ||
42 | opus_int signalType, /* I Signal type */ | ||
43 | const opus_int32 x_Q10[], /* I */ | ||
44 | opus_int8 pulses[], /* O */ | ||
45 | opus_int16 xq[], /* O */ | ||
46 | opus_int32 sLTP_Q15[], /* I/O LTP filter state */ | ||
47 | opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */ | ||
48 | const opus_int16 a_Q12[], /* I Short term prediction coefs */ | ||
49 | const opus_int16 b_Q14[], /* I Long term prediction coefs */ | ||
50 | const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */ | ||
51 | opus_int lag, /* I Pitch lag */ | ||
52 | opus_int32 HarmShapeFIRPacked_Q14, /* I */ | ||
53 | opus_int Tilt_Q14, /* I Spectral tilt */ | ||
54 | opus_int32 LF_shp_Q14, /* I */ | ||
55 | opus_int32 Gain_Q16, /* I */ | ||
56 | opus_int Lambda_Q10, /* I */ | ||
57 | opus_int offset_Q10, /* I */ | ||
58 | opus_int length, /* I Input length */ | ||
59 | opus_int subfr, /* I Subframe number */ | ||
60 | opus_int shapingLPCOrder, /* I Shaping LPC filter order */ | ||
61 | opus_int predictLPCOrder, /* I Prediction filter order */ | ||
62 | opus_int warping_Q16, /* I */ | ||
63 | opus_int nStatesDelayedDecision, /* I Number of states in decision tree */ | ||
64 | opus_int *smpl_buf_idx, /* I/O Index to newest samples in buffers */ | ||
65 | opus_int decisionDelay, /* I */ | ||
66 | int arch /* I */ | ||
67 | ) | ||
68 | { | ||
69 | opus_int i, j, k, Winner_ind, RDmin_ind, RDmax_ind, last_smple_idx; | ||
70 | opus_int32 Winner_rand_state; | ||
71 | opus_int32 LTP_pred_Q14, LPC_pred_Q14, n_AR_Q14, n_LTP_Q14; | ||
72 | opus_int32 n_LF_Q14, r_Q10, rr_Q10, rd1_Q10, rd2_Q10, RDmin_Q10, RDmax_Q10; | ||
73 | opus_int32 q1_Q0, q1_Q10, q2_Q10, exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10; | ||
74 | opus_int32 tmp1, tmp2, sLF_AR_shp_Q14; | ||
75 | opus_int32 *pred_lag_ptr, *shp_lag_ptr, *psLPC_Q14; | ||
76 | NSQ_sample_struct psSampleState[ MAX_DEL_DEC_STATES ][ 2 ]; | ||
77 | NSQ_del_dec_struct *psDD; | ||
78 | NSQ_sample_struct *psSS; | ||
79 | opus_int16 b_Q14_0, b_Q14_1, b_Q14_2, b_Q14_3, b_Q14_4; | ||
80 | opus_int16 a_Q12_0, a_Q12_1, a_Q12_2, a_Q12_3, a_Q12_4, a_Q12_5, a_Q12_6; | ||
81 | opus_int16 a_Q12_7, a_Q12_8, a_Q12_9, a_Q12_10, a_Q12_11, a_Q12_12, a_Q12_13; | ||
82 | opus_int16 a_Q12_14, a_Q12_15; | ||
83 | |||
84 | opus_int32 cur, prev, next; | ||
85 | |||
86 | /*Unused.*/ | ||
87 | (void)arch; | ||
88 | |||
89 | //Intialize b_Q14 variables | ||
90 | b_Q14_0 = b_Q14[ 0 ]; | ||
91 | b_Q14_1 = b_Q14[ 1 ]; | ||
92 | b_Q14_2 = b_Q14[ 2 ]; | ||
93 | b_Q14_3 = b_Q14[ 3 ]; | ||
94 | b_Q14_4 = b_Q14[ 4 ]; | ||
95 | |||
96 | //Intialize a_Q12 variables | ||
97 | a_Q12_0 = a_Q12[0]; | ||
98 | a_Q12_1 = a_Q12[1]; | ||
99 | a_Q12_2 = a_Q12[2]; | ||
100 | a_Q12_3 = a_Q12[3]; | ||
101 | a_Q12_4 = a_Q12[4]; | ||
102 | a_Q12_5 = a_Q12[5]; | ||
103 | a_Q12_6 = a_Q12[6]; | ||
104 | a_Q12_7 = a_Q12[7]; | ||
105 | a_Q12_8 = a_Q12[8]; | ||
106 | a_Q12_9 = a_Q12[9]; | ||
107 | a_Q12_10 = a_Q12[10]; | ||
108 | a_Q12_11 = a_Q12[11]; | ||
109 | a_Q12_12 = a_Q12[12]; | ||
110 | a_Q12_13 = a_Q12[13]; | ||
111 | a_Q12_14 = a_Q12[14]; | ||
112 | a_Q12_15 = a_Q12[15]; | ||
113 | |||
114 | long long temp64; | ||
115 | |||
116 | silk_assert( nStatesDelayedDecision > 0 ); | ||
117 | |||
118 | shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ]; | ||
119 | pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ]; | ||
120 | Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 ); | ||
121 | |||
122 | for( i = 0; i < length; i++ ) { | ||
123 | /* Perform common calculations used in all states */ | ||
124 | |||
125 | /* Long-term prediction */ | ||
126 | if( signalType == TYPE_VOICED ) { | ||
127 | /* Unrolled loop */ | ||
128 | /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ | ||
129 | temp64 = __builtin_mips_mult(pred_lag_ptr[ 0 ], b_Q14_0 ); | ||
130 | temp64 = __builtin_mips_madd( temp64, pred_lag_ptr[ -1 ], b_Q14_1 ); | ||
131 | temp64 = __builtin_mips_madd( temp64, pred_lag_ptr[ -2 ], b_Q14_2 ); | ||
132 | temp64 = __builtin_mips_madd( temp64, pred_lag_ptr[ -3 ], b_Q14_3 ); | ||
133 | temp64 = __builtin_mips_madd( temp64, pred_lag_ptr[ -4 ], b_Q14_4 ); | ||
134 | temp64 += 32768; | ||
135 | LTP_pred_Q14 = __builtin_mips_extr_w(temp64, 16); | ||
136 | LTP_pred_Q14 = silk_LSHIFT( LTP_pred_Q14, 1 ); /* Q13 -> Q14 */ | ||
137 | pred_lag_ptr++; | ||
138 | } else { | ||
139 | LTP_pred_Q14 = 0; | ||
140 | } | ||
141 | |||
142 | /* Long-term shaping */ | ||
143 | if( lag > 0 ) { | ||
144 | /* Symmetric, packed FIR coefficients */ | ||
145 | n_LTP_Q14 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 ); | ||
146 | n_LTP_Q14 = silk_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 ); | ||
147 | n_LTP_Q14 = silk_SUB_LSHIFT32( LTP_pred_Q14, n_LTP_Q14, 2 ); /* Q12 -> Q14 */ | ||
148 | shp_lag_ptr++; | ||
149 | } else { | ||
150 | n_LTP_Q14 = 0; | ||
151 | } | ||
152 | |||
153 | for( k = 0; k < nStatesDelayedDecision; k++ ) { | ||
154 | /* Delayed decision state */ | ||
155 | psDD = &psDelDec[ k ]; | ||
156 | |||
157 | /* Sample state */ | ||
158 | psSS = psSampleState[ k ]; | ||
159 | |||
160 | /* Generate dither */ | ||
161 | psDD->Seed = silk_RAND( psDD->Seed ); | ||
162 | |||
163 | /* Pointer used in short term prediction and shaping */ | ||
164 | psLPC_Q14 = &psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 + i ]; | ||
165 | /* Short-term prediction */ | ||
166 | silk_assert( predictLPCOrder == 10 || predictLPCOrder == 16 ); | ||
167 | temp64 = __builtin_mips_mult(psLPC_Q14[ 0 ], a_Q12_0 ); | ||
168 | temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -1 ], a_Q12_1 ); | ||
169 | temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -2 ], a_Q12_2 ); | ||
170 | temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -3 ], a_Q12_3 ); | ||
171 | temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -4 ], a_Q12_4 ); | ||
172 | temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -5 ], a_Q12_5 ); | ||
173 | temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -6 ], a_Q12_6 ); | ||
174 | temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -7 ], a_Q12_7 ); | ||
175 | temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -8 ], a_Q12_8 ); | ||
176 | temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -9 ], a_Q12_9 ); | ||
177 | if( predictLPCOrder == 16 ) { | ||
178 | temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -10 ], a_Q12_10 ); | ||
179 | temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -11 ], a_Q12_11 ); | ||
180 | temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -12 ], a_Q12_12 ); | ||
181 | temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -13 ], a_Q12_13 ); | ||
182 | temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -14 ], a_Q12_14 ); | ||
183 | temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -15 ], a_Q12_15 ); | ||
184 | } | ||
185 | temp64 += 32768; | ||
186 | LPC_pred_Q14 = __builtin_mips_extr_w(temp64, 16); | ||
187 | |||
188 | LPC_pred_Q14 = silk_LSHIFT( LPC_pred_Q14, 4 ); /* Q10 -> Q14 */ | ||
189 | |||
190 | /* Noise shape feedback */ | ||
191 | silk_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */ | ||
192 | /* Output of lowpass section */ | ||
193 | tmp2 = silk_SMLAWB( psLPC_Q14[ 0 ], psDD->sAR2_Q14[ 0 ], warping_Q16 ); | ||
194 | /* Output of allpass section */ | ||
195 | tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ 0 ], psDD->sAR2_Q14[ 1 ] - tmp2, warping_Q16 ); | ||
196 | psDD->sAR2_Q14[ 0 ] = tmp2; | ||
197 | |||
198 | temp64 = __builtin_mips_mult(tmp2, AR_shp_Q13[ 0 ] ); | ||
199 | |||
200 | prev = psDD->sAR2_Q14[ 1 ]; | ||
201 | |||
202 | /* Loop over allpass sections */ | ||
203 | for( j = 2; j < shapingLPCOrder; j += 2 ) { | ||
204 | cur = psDD->sAR2_Q14[ j ]; | ||
205 | next = psDD->sAR2_Q14[ j+1 ]; | ||
206 | /* Output of allpass section */ | ||
207 | tmp2 = silk_SMLAWB( prev, cur - tmp1, warping_Q16 ); | ||
208 | psDD->sAR2_Q14[ j - 1 ] = tmp1; | ||
209 | temp64 = __builtin_mips_madd( temp64, tmp1, AR_shp_Q13[ j - 1 ] ); | ||
210 | temp64 = __builtin_mips_madd( temp64, tmp2, AR_shp_Q13[ j ] ); | ||
211 | /* Output of allpass section */ | ||
212 | tmp1 = silk_SMLAWB( cur, next - tmp2, warping_Q16 ); | ||
213 | psDD->sAR2_Q14[ j + 0 ] = tmp2; | ||
214 | prev = next; | ||
215 | } | ||
216 | psDD->sAR2_Q14[ shapingLPCOrder - 1 ] = tmp1; | ||
217 | temp64 = __builtin_mips_madd( temp64, tmp1, AR_shp_Q13[ shapingLPCOrder - 1 ] ); | ||
218 | temp64 += 32768; | ||
219 | n_AR_Q14 = __builtin_mips_extr_w(temp64, 16); | ||
220 | n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 1 ); /* Q11 -> Q12 */ | ||
221 | n_AR_Q14 = silk_SMLAWB( n_AR_Q14, psDD->LF_AR_Q14, Tilt_Q14 ); /* Q12 */ | ||
222 | n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 2 ); /* Q12 -> Q14 */ | ||
223 | |||
224 | n_LF_Q14 = silk_SMULWB( psDD->Shape_Q14[ *smpl_buf_idx ], LF_shp_Q14 ); /* Q12 */ | ||
225 | n_LF_Q14 = silk_SMLAWT( n_LF_Q14, psDD->LF_AR_Q14, LF_shp_Q14 ); /* Q12 */ | ||
226 | n_LF_Q14 = silk_LSHIFT( n_LF_Q14, 2 ); /* Q12 -> Q14 */ | ||
227 | |||
228 | /* Input minus prediction plus noise feedback */ | ||
229 | /* r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP */ | ||
230 | tmp1 = silk_ADD32( n_AR_Q14, n_LF_Q14 ); /* Q14 */ | ||
231 | tmp2 = silk_ADD32( n_LTP_Q14, LPC_pred_Q14 ); /* Q13 */ | ||
232 | tmp1 = silk_SUB32( tmp2, tmp1 ); /* Q13 */ | ||
233 | tmp1 = silk_RSHIFT_ROUND( tmp1, 4 ); /* Q10 */ | ||
234 | |||
235 | r_Q10 = silk_SUB32( x_Q10[ i ], tmp1 ); /* residual error Q10 */ | ||
236 | |||
237 | /* Flip sign depending on dither */ | ||
238 | if ( psDD->Seed < 0 ) { | ||
239 | r_Q10 = -r_Q10; | ||
240 | } | ||
241 | r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 ); | ||
242 | |||
243 | /* Find two quantization level candidates and measure their rate-distortion */ | ||
244 | q1_Q10 = silk_SUB32( r_Q10, offset_Q10 ); | ||
245 | q1_Q0 = silk_RSHIFT( q1_Q10, 10 ); | ||
246 | if( q1_Q0 > 0 ) { | ||
247 | q1_Q10 = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 ); | ||
248 | q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 ); | ||
249 | q2_Q10 = silk_ADD32( q1_Q10, 1024 ); | ||
250 | rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 ); | ||
251 | rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 ); | ||
252 | } else if( q1_Q0 == 0 ) { | ||
253 | q1_Q10 = offset_Q10; | ||
254 | q2_Q10 = silk_ADD32( q1_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 ); | ||
255 | rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 ); | ||
256 | rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 ); | ||
257 | } else if( q1_Q0 == -1 ) { | ||
258 | q2_Q10 = offset_Q10; | ||
259 | q1_Q10 = silk_SUB32( q2_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 ); | ||
260 | rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 ); | ||
261 | rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 ); | ||
262 | } else { /* q1_Q0 < -1 */ | ||
263 | q1_Q10 = silk_ADD32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 ); | ||
264 | q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 ); | ||
265 | q2_Q10 = silk_ADD32( q1_Q10, 1024 ); | ||
266 | rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 ); | ||
267 | rd2_Q10 = silk_SMULBB( -q2_Q10, Lambda_Q10 ); | ||
268 | } | ||
269 | rr_Q10 = silk_SUB32( r_Q10, q1_Q10 ); | ||
270 | rd1_Q10 = silk_RSHIFT( silk_SMLABB( rd1_Q10, rr_Q10, rr_Q10 ), 10 ); | ||
271 | rr_Q10 = silk_SUB32( r_Q10, q2_Q10 ); | ||
272 | rd2_Q10 = silk_RSHIFT( silk_SMLABB( rd2_Q10, rr_Q10, rr_Q10 ), 10 ); | ||
273 | |||
274 | if( rd1_Q10 < rd2_Q10 ) { | ||
275 | psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 ); | ||
276 | psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 ); | ||
277 | psSS[ 0 ].Q_Q10 = q1_Q10; | ||
278 | psSS[ 1 ].Q_Q10 = q2_Q10; | ||
279 | } else { | ||
280 | psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 ); | ||
281 | psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 ); | ||
282 | psSS[ 0 ].Q_Q10 = q2_Q10; | ||
283 | psSS[ 1 ].Q_Q10 = q1_Q10; | ||
284 | } | ||
285 | |||
286 | /* Update states for best quantization */ | ||
287 | |||
288 | /* Quantized excitation */ | ||
289 | exc_Q14 = silk_LSHIFT32( psSS[ 0 ].Q_Q10, 4 ); | ||
290 | if ( psDD->Seed < 0 ) { | ||
291 | exc_Q14 = -exc_Q14; | ||
292 | } | ||
293 | |||
294 | /* Add predictions */ | ||
295 | LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 ); | ||
296 | xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 ); | ||
297 | |||
298 | /* Update states */ | ||
299 | sLF_AR_shp_Q14 = silk_SUB32( xq_Q14, n_AR_Q14 ); | ||
300 | psSS[ 0 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 ); | ||
301 | psSS[ 0 ].LF_AR_Q14 = sLF_AR_shp_Q14; | ||
302 | psSS[ 0 ].LPC_exc_Q14 = LPC_exc_Q14; | ||
303 | psSS[ 0 ].xq_Q14 = xq_Q14; | ||
304 | |||
305 | /* Update states for second best quantization */ | ||
306 | |||
307 | /* Quantized excitation */ | ||
308 | exc_Q14 = silk_LSHIFT32( psSS[ 1 ].Q_Q10, 4 ); | ||
309 | if ( psDD->Seed < 0 ) { | ||
310 | exc_Q14 = -exc_Q14; | ||
311 | } | ||
312 | |||
313 | |||
314 | /* Add predictions */ | ||
315 | LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 ); | ||
316 | xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 ); | ||
317 | |||
318 | /* Update states */ | ||
319 | sLF_AR_shp_Q14 = silk_SUB32( xq_Q14, n_AR_Q14 ); | ||
320 | psSS[ 1 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 ); | ||
321 | psSS[ 1 ].LF_AR_Q14 = sLF_AR_shp_Q14; | ||
322 | psSS[ 1 ].LPC_exc_Q14 = LPC_exc_Q14; | ||
323 | psSS[ 1 ].xq_Q14 = xq_Q14; | ||
324 | } | ||
325 | |||
326 | *smpl_buf_idx = ( *smpl_buf_idx - 1 ) % DECISION_DELAY; | ||
327 | if( *smpl_buf_idx < 0 ) *smpl_buf_idx += DECISION_DELAY; | ||
328 | last_smple_idx = ( *smpl_buf_idx + decisionDelay ) % DECISION_DELAY; | ||
329 | |||
330 | /* Find winner */ | ||
331 | RDmin_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10; | ||
332 | Winner_ind = 0; | ||
333 | for( k = 1; k < nStatesDelayedDecision; k++ ) { | ||
334 | if( psSampleState[ k ][ 0 ].RD_Q10 < RDmin_Q10 ) { | ||
335 | RDmin_Q10 = psSampleState[ k ][ 0 ].RD_Q10; | ||
336 | Winner_ind = k; | ||
337 | } | ||
338 | } | ||
339 | |||
340 | /* Increase RD values of expired states */ | ||
341 | Winner_rand_state = psDelDec[ Winner_ind ].RandState[ last_smple_idx ]; | ||
342 | for( k = 0; k < nStatesDelayedDecision; k++ ) { | ||
343 | if( psDelDec[ k ].RandState[ last_smple_idx ] != Winner_rand_state ) { | ||
344 | psSampleState[ k ][ 0 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 0 ].RD_Q10, silk_int32_MAX >> 4 ); | ||
345 | psSampleState[ k ][ 1 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 1 ].RD_Q10, silk_int32_MAX >> 4 ); | ||
346 | silk_assert( psSampleState[ k ][ 0 ].RD_Q10 >= 0 ); | ||
347 | } | ||
348 | } | ||
349 | |||
350 | /* Find worst in first set and best in second set */ | ||
351 | RDmax_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10; | ||
352 | RDmin_Q10 = psSampleState[ 0 ][ 1 ].RD_Q10; | ||
353 | RDmax_ind = 0; | ||
354 | RDmin_ind = 0; | ||
355 | for( k = 1; k < nStatesDelayedDecision; k++ ) { | ||
356 | /* find worst in first set */ | ||
357 | if( psSampleState[ k ][ 0 ].RD_Q10 > RDmax_Q10 ) { | ||
358 | RDmax_Q10 = psSampleState[ k ][ 0 ].RD_Q10; | ||
359 | RDmax_ind = k; | ||
360 | } | ||
361 | /* find best in second set */ | ||
362 | if( psSampleState[ k ][ 1 ].RD_Q10 < RDmin_Q10 ) { | ||
363 | RDmin_Q10 = psSampleState[ k ][ 1 ].RD_Q10; | ||
364 | RDmin_ind = k; | ||
365 | } | ||
366 | } | ||
367 | |||
368 | /* Replace a state if best from second set outperforms worst in first set */ | ||
369 | if( RDmin_Q10 < RDmax_Q10 ) { | ||
370 | silk_memcpy( ( (opus_int32 *)&psDelDec[ RDmax_ind ] ) + i, | ||
371 | ( (opus_int32 *)&psDelDec[ RDmin_ind ] ) + i, sizeof( NSQ_del_dec_struct ) - i * sizeof( opus_int32) ); | ||
372 | silk_memcpy( &psSampleState[ RDmax_ind ][ 0 ], &psSampleState[ RDmin_ind ][ 1 ], sizeof( NSQ_sample_struct ) ); | ||
373 | } | ||
374 | |||
375 | /* Write samples from winner to output and long-term filter states */ | ||
376 | psDD = &psDelDec[ Winner_ind ]; | ||
377 | if( subfr > 0 || i >= decisionDelay ) { | ||
378 | pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 ); | ||
379 | xq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( | ||
380 | silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], delayedGain_Q10[ last_smple_idx ] ), 8 ) ); | ||
381 | NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay ] = psDD->Shape_Q14[ last_smple_idx ]; | ||
382 | sLTP_Q15[ NSQ->sLTP_buf_idx - decisionDelay ] = psDD->Pred_Q15[ last_smple_idx ]; | ||
383 | } | ||
384 | NSQ->sLTP_shp_buf_idx++; | ||
385 | NSQ->sLTP_buf_idx++; | ||
386 | |||
387 | /* Update states */ | ||
388 | for( k = 0; k < nStatesDelayedDecision; k++ ) { | ||
389 | psDD = &psDelDec[ k ]; | ||
390 | psSS = &psSampleState[ k ][ 0 ]; | ||
391 | psDD->LF_AR_Q14 = psSS->LF_AR_Q14; | ||
392 | psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH + i ] = psSS->xq_Q14; | ||
393 | psDD->Xq_Q14[ *smpl_buf_idx ] = psSS->xq_Q14; | ||
394 | psDD->Q_Q10[ *smpl_buf_idx ] = psSS->Q_Q10; | ||
395 | psDD->Pred_Q15[ *smpl_buf_idx ] = silk_LSHIFT32( psSS->LPC_exc_Q14, 1 ); | ||
396 | psDD->Shape_Q14[ *smpl_buf_idx ] = psSS->sLTP_shp_Q14; | ||
397 | psDD->Seed = silk_ADD32_ovflw( psDD->Seed, silk_RSHIFT_ROUND( psSS->Q_Q10, 10 ) ); | ||
398 | psDD->RandState[ *smpl_buf_idx ] = psDD->Seed; | ||
399 | psDD->RD_Q10 = psSS->RD_Q10; | ||
400 | } | ||
401 | delayedGain_Q10[ *smpl_buf_idx ] = Gain_Q10; | ||
402 | } | ||
403 | /* Update LPC states */ | ||
404 | for( k = 0; k < nStatesDelayedDecision; k++ ) { | ||
405 | psDD = &psDelDec[ k ]; | ||
406 | silk_memcpy( psDD->sLPC_Q14, &psDD->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) ); | ||
407 | } | ||
408 | } | ||
409 | |||
410 | #endif /* __NSQ_DEL_DEC_MIPSR1_H__ */ | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/mips/macros_mipsr1.h b/lib/rbcodec/codecs/libopus/silk/mips/macros_mipsr1.h new file mode 100644 index 0000000000..12ed981a6e --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/mips/macros_mipsr1.h | |||
@@ -0,0 +1,92 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | |||
29 | #ifndef __SILK_MACROS_MIPSR1_H__ | ||
30 | #define __SILK_MACROS_MIPSR1_H__ | ||
31 | |||
32 | #define mips_clz(x) __builtin_clz(x) | ||
33 | |||
34 | #undef silk_SMULWB | ||
35 | static inline int silk_SMULWB(int a, int b) | ||
36 | { | ||
37 | long long ac; | ||
38 | int c; | ||
39 | |||
40 | ac = __builtin_mips_mult(a, (opus_int32)(opus_int16)b); | ||
41 | c = __builtin_mips_extr_w(ac, 16); | ||
42 | |||
43 | return c; | ||
44 | } | ||
45 | |||
46 | #undef silk_SMLAWB | ||
47 | #define silk_SMLAWB(a32, b32, c32) ((a32) + silk_SMULWB(b32, c32)) | ||
48 | |||
49 | #undef silk_SMULWW | ||
50 | static inline int silk_SMULWW(int a, int b) | ||
51 | { | ||
52 | long long ac; | ||
53 | int c; | ||
54 | |||
55 | ac = __builtin_mips_mult(a, b); | ||
56 | c = __builtin_mips_extr_w(ac, 16); | ||
57 | |||
58 | return c; | ||
59 | } | ||
60 | |||
61 | #undef silk_SMLAWW | ||
62 | static inline int silk_SMLAWW(int a, int b, int c) | ||
63 | { | ||
64 | long long ac; | ||
65 | int res; | ||
66 | |||
67 | ac = __builtin_mips_mult(b, c); | ||
68 | res = __builtin_mips_extr_w(ac, 16); | ||
69 | res += a; | ||
70 | |||
71 | return res; | ||
72 | } | ||
73 | |||
74 | #define OVERRIDE_silk_CLZ16 | ||
75 | static inline opus_int32 silk_CLZ16(opus_int16 in16) | ||
76 | { | ||
77 | int re32; | ||
78 | opus_int32 in32 = (opus_int32 )in16; | ||
79 | re32 = mips_clz(in32); | ||
80 | re32-=16; | ||
81 | return re32; | ||
82 | } | ||
83 | |||
84 | #define OVERRIDE_silk_CLZ32 | ||
85 | static inline opus_int32 silk_CLZ32(opus_int32 in32) | ||
86 | { | ||
87 | int re32; | ||
88 | re32 = mips_clz(in32); | ||
89 | return re32; | ||
90 | } | ||
91 | |||
92 | #endif /* __SILK_MACROS_MIPSR1_H__ */ | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/mips/sigproc_fix_mipsr1.h b/lib/rbcodec/codecs/libopus/silk/mips/sigproc_fix_mipsr1.h new file mode 100644 index 0000000000..51520c0a6f --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/mips/sigproc_fix_mipsr1.h | |||
@@ -0,0 +1,60 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifndef SILK_SIGPROC_FIX_MIPSR1_H | ||
29 | #define SILK_SIGPROC_FIX_MIPSR1_H | ||
30 | |||
31 | #undef silk_SAT16 | ||
32 | static inline short int silk_SAT16(int a) | ||
33 | { | ||
34 | int c; | ||
35 | c = __builtin_mips_shll_s_w(a, 16); | ||
36 | c = c>>16; | ||
37 | |||
38 | return c; | ||
39 | } | ||
40 | |||
41 | #undef silk_LSHIFT_SAT32 | ||
42 | static inline int silk_LSHIFT_SAT32(int a, int shift) | ||
43 | { | ||
44 | int r; | ||
45 | |||
46 | r = __builtin_mips_shll_s_w(a, shift); | ||
47 | |||
48 | return r; | ||
49 | } | ||
50 | |||
51 | #undef silk_RSHIFT_ROUND | ||
52 | static inline int silk_RSHIFT_ROUND(int a, int shift) | ||
53 | { | ||
54 | int r; | ||
55 | |||
56 | r = __builtin_mips_shra_r_w(a, shift); | ||
57 | return r; | ||
58 | } | ||
59 | |||
60 | #endif /* SILK_SIGPROC_FIX_MIPSR1_H */ | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/process_NLSFs.c b/lib/rbcodec/codecs/libopus/silk/process_NLSFs.c new file mode 100644 index 0000000000..d130809541 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/process_NLSFs.c | |||
@@ -0,0 +1,107 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main.h" | ||
33 | |||
34 | /* Limit, stabilize, convert and quantize NLSFs */ | ||
35 | void silk_process_NLSFs( | ||
36 | silk_encoder_state *psEncC, /* I/O Encoder state */ | ||
37 | opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ], /* O Prediction coefficients */ | ||
38 | opus_int16 pNLSF_Q15[ MAX_LPC_ORDER ], /* I/O Normalized LSFs (quant out) (0 - (2^15-1)) */ | ||
39 | const opus_int16 prev_NLSFq_Q15[ MAX_LPC_ORDER ] /* I Previous Normalized LSFs (0 - (2^15-1)) */ | ||
40 | ) | ||
41 | { | ||
42 | opus_int i, doInterpolate; | ||
43 | opus_int NLSF_mu_Q20; | ||
44 | opus_int16 i_sqr_Q15; | ||
45 | opus_int16 pNLSF0_temp_Q15[ MAX_LPC_ORDER ]; | ||
46 | opus_int16 pNLSFW_QW[ MAX_LPC_ORDER ]; | ||
47 | opus_int16 pNLSFW0_temp_QW[ MAX_LPC_ORDER ]; | ||
48 | |||
49 | silk_assert( psEncC->speech_activity_Q8 >= 0 ); | ||
50 | silk_assert( psEncC->speech_activity_Q8 <= SILK_FIX_CONST( 1.0, 8 ) ); | ||
51 | celt_assert( psEncC->useInterpolatedNLSFs == 1 || psEncC->indices.NLSFInterpCoef_Q2 == ( 1 << 2 ) ); | ||
52 | |||
53 | /***********************/ | ||
54 | /* Calculate mu values */ | ||
55 | /***********************/ | ||
56 | /* NLSF_mu = 0.003 - 0.0015 * psEnc->speech_activity; */ | ||
57 | NLSF_mu_Q20 = silk_SMLAWB( SILK_FIX_CONST( 0.003, 20 ), SILK_FIX_CONST( -0.001, 28 ), psEncC->speech_activity_Q8 ); | ||
58 | if( psEncC->nb_subfr == 2 ) { | ||
59 | /* Multiply by 1.5 for 10 ms packets */ | ||
60 | NLSF_mu_Q20 = silk_ADD_RSHIFT( NLSF_mu_Q20, NLSF_mu_Q20, 1 ); | ||
61 | } | ||
62 | |||
63 | celt_assert( NLSF_mu_Q20 > 0 ); | ||
64 | silk_assert( NLSF_mu_Q20 <= SILK_FIX_CONST( 0.005, 20 ) ); | ||
65 | |||
66 | /* Calculate NLSF weights */ | ||
67 | silk_NLSF_VQ_weights_laroia( pNLSFW_QW, pNLSF_Q15, psEncC->predictLPCOrder ); | ||
68 | |||
69 | /* Update NLSF weights for interpolated NLSFs */ | ||
70 | doInterpolate = ( psEncC->useInterpolatedNLSFs == 1 ) && ( psEncC->indices.NLSFInterpCoef_Q2 < 4 ); | ||
71 | if( doInterpolate ) { | ||
72 | /* Calculate the interpolated NLSF vector for the first half */ | ||
73 | silk_interpolate( pNLSF0_temp_Q15, prev_NLSFq_Q15, pNLSF_Q15, | ||
74 | psEncC->indices.NLSFInterpCoef_Q2, psEncC->predictLPCOrder ); | ||
75 | |||
76 | /* Calculate first half NLSF weights for the interpolated NLSFs */ | ||
77 | silk_NLSF_VQ_weights_laroia( pNLSFW0_temp_QW, pNLSF0_temp_Q15, psEncC->predictLPCOrder ); | ||
78 | |||
79 | /* Update NLSF weights with contribution from first half */ | ||
80 | i_sqr_Q15 = silk_LSHIFT( silk_SMULBB( psEncC->indices.NLSFInterpCoef_Q2, psEncC->indices.NLSFInterpCoef_Q2 ), 11 ); | ||
81 | for( i = 0; i < psEncC->predictLPCOrder; i++ ) { | ||
82 | pNLSFW_QW[ i ] = silk_ADD16( silk_RSHIFT( pNLSFW_QW[ i ], 1 ), silk_RSHIFT( | ||
83 | silk_SMULBB( pNLSFW0_temp_QW[ i ], i_sqr_Q15 ), 16) ); | ||
84 | silk_assert( pNLSFW_QW[ i ] >= 1 ); | ||
85 | } | ||
86 | } | ||
87 | |||
88 | silk_NLSF_encode( psEncC->indices.NLSFIndices, pNLSF_Q15, psEncC->psNLSF_CB, pNLSFW_QW, | ||
89 | NLSF_mu_Q20, psEncC->NLSF_MSVQ_Survivors, psEncC->indices.signalType ); | ||
90 | |||
91 | /* Convert quantized NLSFs back to LPC coefficients */ | ||
92 | silk_NLSF2A( PredCoef_Q12[ 1 ], pNLSF_Q15, psEncC->predictLPCOrder, psEncC->arch ); | ||
93 | |||
94 | if( doInterpolate ) { | ||
95 | /* Calculate the interpolated, quantized LSF vector for the first half */ | ||
96 | silk_interpolate( pNLSF0_temp_Q15, prev_NLSFq_Q15, pNLSF_Q15, | ||
97 | psEncC->indices.NLSFInterpCoef_Q2, psEncC->predictLPCOrder ); | ||
98 | |||
99 | /* Convert back to LPC coefficients */ | ||
100 | silk_NLSF2A( PredCoef_Q12[ 0 ], pNLSF0_temp_Q15, psEncC->predictLPCOrder, psEncC->arch ); | ||
101 | |||
102 | } else { | ||
103 | /* Copy LPC coefficients for first half from second half */ | ||
104 | celt_assert( psEncC->predictLPCOrder <= MAX_LPC_ORDER ); | ||
105 | silk_memcpy( PredCoef_Q12[ 0 ], PredCoef_Q12[ 1 ], psEncC->predictLPCOrder * sizeof( opus_int16 ) ); | ||
106 | } | ||
107 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/quant_LTP_gains.c b/lib/rbcodec/codecs/libopus/silk/quant_LTP_gains.c new file mode 100644 index 0000000000..d6b8eff8d1 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/quant_LTP_gains.c | |||
@@ -0,0 +1,132 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main.h" | ||
33 | #include "tuning_parameters.h" | ||
34 | |||
35 | void silk_quant_LTP_gains( | ||
36 | opus_int16 B_Q14[ MAX_NB_SUBFR * LTP_ORDER ], /* O Quantized LTP gains */ | ||
37 | opus_int8 cbk_index[ MAX_NB_SUBFR ], /* O Codebook Index */ | ||
38 | opus_int8 *periodicity_index, /* O Periodicity Index */ | ||
39 | opus_int32 *sum_log_gain_Q7, /* I/O Cumulative max prediction gain */ | ||
40 | opus_int *pred_gain_dB_Q7, /* O LTP prediction gain */ | ||
41 | const opus_int32 XX_Q17[ MAX_NB_SUBFR*LTP_ORDER*LTP_ORDER ], /* I Correlation matrix in Q18 */ | ||
42 | const opus_int32 xX_Q17[ MAX_NB_SUBFR*LTP_ORDER ], /* I Correlation vector in Q18 */ | ||
43 | const opus_int subfr_len, /* I Number of samples per subframe */ | ||
44 | const opus_int nb_subfr, /* I Number of subframes */ | ||
45 | int arch /* I Run-time architecture */ | ||
46 | ) | ||
47 | { | ||
48 | opus_int j, k, cbk_size; | ||
49 | opus_int8 temp_idx[ MAX_NB_SUBFR ]; | ||
50 | const opus_uint8 *cl_ptr_Q5; | ||
51 | const opus_int8 *cbk_ptr_Q7; | ||
52 | const opus_uint8 *cbk_gain_ptr_Q7; | ||
53 | const opus_int32 *XX_Q17_ptr, *xX_Q17_ptr; | ||
54 | opus_int32 res_nrg_Q15_subfr, res_nrg_Q15, rate_dist_Q7_subfr, rate_dist_Q7, min_rate_dist_Q7; | ||
55 | opus_int32 sum_log_gain_tmp_Q7, best_sum_log_gain_Q7, max_gain_Q7; | ||
56 | opus_int gain_Q7; | ||
57 | |||
58 | /***************************************************/ | ||
59 | /* iterate over different codebooks with different */ | ||
60 | /* rates/distortions, and choose best */ | ||
61 | /***************************************************/ | ||
62 | min_rate_dist_Q7 = silk_int32_MAX; | ||
63 | best_sum_log_gain_Q7 = 0; | ||
64 | for( k = 0; k < 3; k++ ) { | ||
65 | /* Safety margin for pitch gain control, to take into account factors | ||
66 | such as state rescaling/rewhitening. */ | ||
67 | opus_int32 gain_safety = SILK_FIX_CONST( 0.4, 7 ); | ||
68 | |||
69 | cl_ptr_Q5 = silk_LTP_gain_BITS_Q5_ptrs[ k ]; | ||
70 | cbk_ptr_Q7 = silk_LTP_vq_ptrs_Q7[ k ]; | ||
71 | cbk_gain_ptr_Q7 = silk_LTP_vq_gain_ptrs_Q7[ k ]; | ||
72 | cbk_size = silk_LTP_vq_sizes[ k ]; | ||
73 | |||
74 | /* Set up pointers to first subframe */ | ||
75 | XX_Q17_ptr = XX_Q17; | ||
76 | xX_Q17_ptr = xX_Q17; | ||
77 | |||
78 | res_nrg_Q15 = 0; | ||
79 | rate_dist_Q7 = 0; | ||
80 | sum_log_gain_tmp_Q7 = *sum_log_gain_Q7; | ||
81 | for( j = 0; j < nb_subfr; j++ ) { | ||
82 | max_gain_Q7 = silk_log2lin( ( SILK_FIX_CONST( MAX_SUM_LOG_GAIN_DB / 6.0, 7 ) - sum_log_gain_tmp_Q7 ) | ||
83 | + SILK_FIX_CONST( 7, 7 ) ) - gain_safety; | ||
84 | silk_VQ_WMat_EC( | ||
85 | &temp_idx[ j ], /* O index of best codebook vector */ | ||
86 | &res_nrg_Q15_subfr, /* O residual energy */ | ||
87 | &rate_dist_Q7_subfr, /* O best weighted quantization error + mu * rate */ | ||
88 | &gain_Q7, /* O sum of absolute LTP coefficients */ | ||
89 | XX_Q17_ptr, /* I correlation matrix */ | ||
90 | xX_Q17_ptr, /* I correlation vector */ | ||
91 | cbk_ptr_Q7, /* I codebook */ | ||
92 | cbk_gain_ptr_Q7, /* I codebook effective gains */ | ||
93 | cl_ptr_Q5, /* I code length for each codebook vector */ | ||
94 | subfr_len, /* I number of samples per subframe */ | ||
95 | max_gain_Q7, /* I maximum sum of absolute LTP coefficients */ | ||
96 | cbk_size, /* I number of vectors in codebook */ | ||
97 | arch /* I Run-time architecture */ | ||
98 | ); | ||
99 | |||
100 | res_nrg_Q15 = silk_ADD_POS_SAT32( res_nrg_Q15, res_nrg_Q15_subfr ); | ||
101 | rate_dist_Q7 = silk_ADD_POS_SAT32( rate_dist_Q7, rate_dist_Q7_subfr ); | ||
102 | sum_log_gain_tmp_Q7 = silk_max(0, sum_log_gain_tmp_Q7 | ||
103 | + silk_lin2log( gain_safety + gain_Q7 ) - SILK_FIX_CONST( 7, 7 )); | ||
104 | |||
105 | XX_Q17_ptr += LTP_ORDER * LTP_ORDER; | ||
106 | xX_Q17_ptr += LTP_ORDER; | ||
107 | } | ||
108 | |||
109 | if( rate_dist_Q7 <= min_rate_dist_Q7 ) { | ||
110 | min_rate_dist_Q7 = rate_dist_Q7; | ||
111 | *periodicity_index = (opus_int8)k; | ||
112 | silk_memcpy( cbk_index, temp_idx, nb_subfr * sizeof( opus_int8 ) ); | ||
113 | best_sum_log_gain_Q7 = sum_log_gain_tmp_Q7; | ||
114 | } | ||
115 | } | ||
116 | |||
117 | cbk_ptr_Q7 = silk_LTP_vq_ptrs_Q7[ *periodicity_index ]; | ||
118 | for( j = 0; j < nb_subfr; j++ ) { | ||
119 | for( k = 0; k < LTP_ORDER; k++ ) { | ||
120 | B_Q14[ j * LTP_ORDER + k ] = silk_LSHIFT( cbk_ptr_Q7[ cbk_index[ j ] * LTP_ORDER + k ], 7 ); | ||
121 | } | ||
122 | } | ||
123 | |||
124 | if( nb_subfr == 2 ) { | ||
125 | res_nrg_Q15 = silk_RSHIFT32( res_nrg_Q15, 1 ); | ||
126 | } else { | ||
127 | res_nrg_Q15 = silk_RSHIFT32( res_nrg_Q15, 2 ); | ||
128 | } | ||
129 | |||
130 | *sum_log_gain_Q7 = best_sum_log_gain_Q7; | ||
131 | *pred_gain_dB_Q7 = (opus_int)silk_SMULBB( -3, silk_lin2log( res_nrg_Q15 ) - ( 15 << 7 ) ); | ||
132 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/resampler.c b/lib/rbcodec/codecs/libopus/silk/resampler.c index 374fbb3722..1f11e50891 100644 --- a/lib/rbcodec/codecs/libopus/silk/resampler.c +++ b/lib/rbcodec/codecs/libopus/silk/resampler.c | |||
@@ -91,14 +91,14 @@ opus_int silk_resampler_init( | |||
91 | if( forEnc ) { | 91 | if( forEnc ) { |
92 | if( ( Fs_Hz_in != 8000 && Fs_Hz_in != 12000 && Fs_Hz_in != 16000 && Fs_Hz_in != 24000 && Fs_Hz_in != 48000 ) || | 92 | if( ( Fs_Hz_in != 8000 && Fs_Hz_in != 12000 && Fs_Hz_in != 16000 && Fs_Hz_in != 24000 && Fs_Hz_in != 48000 ) || |
93 | ( Fs_Hz_out != 8000 && Fs_Hz_out != 12000 && Fs_Hz_out != 16000 ) ) { | 93 | ( Fs_Hz_out != 8000 && Fs_Hz_out != 12000 && Fs_Hz_out != 16000 ) ) { |
94 | silk_assert( 0 ); | 94 | celt_assert( 0 ); |
95 | return -1; | 95 | return -1; |
96 | } | 96 | } |
97 | S->inputDelay = delay_matrix_enc[ rateID( Fs_Hz_in ) ][ rateID( Fs_Hz_out ) ]; | 97 | S->inputDelay = delay_matrix_enc[ rateID( Fs_Hz_in ) ][ rateID( Fs_Hz_out ) ]; |
98 | } else { | 98 | } else { |
99 | if( ( Fs_Hz_in != 8000 && Fs_Hz_in != 12000 && Fs_Hz_in != 16000 ) || | 99 | if( ( Fs_Hz_in != 8000 && Fs_Hz_in != 12000 && Fs_Hz_in != 16000 ) || |
100 | ( Fs_Hz_out != 8000 && Fs_Hz_out != 12000 && Fs_Hz_out != 16000 && Fs_Hz_out != 24000 && Fs_Hz_out != 48000 ) ) { | 100 | ( Fs_Hz_out != 8000 && Fs_Hz_out != 12000 && Fs_Hz_out != 16000 && Fs_Hz_out != 24000 && Fs_Hz_out != 48000 ) ) { |
101 | silk_assert( 0 ); | 101 | celt_assert( 0 ); |
102 | return -1; | 102 | return -1; |
103 | } | 103 | } |
104 | S->inputDelay = delay_matrix_dec[ rateID( Fs_Hz_in ) ][ rateID( Fs_Hz_out ) ]; | 104 | S->inputDelay = delay_matrix_dec[ rateID( Fs_Hz_in ) ][ rateID( Fs_Hz_out ) ]; |
@@ -151,7 +151,7 @@ opus_int silk_resampler_init( | |||
151 | S->Coefs = silk_Resampler_1_6_COEFS; | 151 | S->Coefs = silk_Resampler_1_6_COEFS; |
152 | } else { | 152 | } else { |
153 | /* None available */ | 153 | /* None available */ |
154 | silk_assert( 0 ); | 154 | celt_assert( 0 ); |
155 | return -1; | 155 | return -1; |
156 | } | 156 | } |
157 | } else { | 157 | } else { |
@@ -181,9 +181,9 @@ opus_int silk_resampler( | |||
181 | opus_int nSamples; | 181 | opus_int nSamples; |
182 | 182 | ||
183 | /* Need at least 1 ms of input data */ | 183 | /* Need at least 1 ms of input data */ |
184 | silk_assert( inLen >= S->Fs_in_kHz ); | 184 | celt_assert( inLen >= S->Fs_in_kHz ); |
185 | /* Delay can't exceed the 1 ms of buffering */ | 185 | /* Delay can't exceed the 1 ms of buffering */ |
186 | silk_assert( S->inputDelay <= S->Fs_in_kHz ); | 186 | celt_assert( S->inputDelay <= S->Fs_in_kHz ); |
187 | 187 | ||
188 | nSamples = S->Fs_in_kHz - S->inputDelay; | 188 | nSamples = S->Fs_in_kHz - S->inputDelay; |
189 | 189 | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/resampler_down2.c b/lib/rbcodec/codecs/libopus/silk/resampler_down2.c new file mode 100644 index 0000000000..971d7bfd4a --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/resampler_down2.c | |||
@@ -0,0 +1,74 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "SigProc_FIX.h" | ||
33 | #include "resampler_rom.h" | ||
34 | |||
35 | /* Downsample by a factor 2 */ | ||
36 | void silk_resampler_down2( | ||
37 | opus_int32 *S, /* I/O State vector [ 2 ] */ | ||
38 | opus_int16 *out, /* O Output signal [ floor(len/2) ] */ | ||
39 | const opus_int16 *in, /* I Input signal [ len ] */ | ||
40 | opus_int32 inLen /* I Number of input samples */ | ||
41 | ) | ||
42 | { | ||
43 | opus_int32 k, len2 = silk_RSHIFT32( inLen, 1 ); | ||
44 | opus_int32 in32, out32, Y, X; | ||
45 | |||
46 | celt_assert( silk_resampler_down2_0 > 0 ); | ||
47 | celt_assert( silk_resampler_down2_1 < 0 ); | ||
48 | |||
49 | /* Internal variables and state are in Q10 format */ | ||
50 | for( k = 0; k < len2; k++ ) { | ||
51 | /* Convert to Q10 */ | ||
52 | in32 = silk_LSHIFT( (opus_int32)in[ 2 * k ], 10 ); | ||
53 | |||
54 | /* All-pass section for even input sample */ | ||
55 | Y = silk_SUB32( in32, S[ 0 ] ); | ||
56 | X = silk_SMLAWB( Y, Y, silk_resampler_down2_1 ); | ||
57 | out32 = silk_ADD32( S[ 0 ], X ); | ||
58 | S[ 0 ] = silk_ADD32( in32, X ); | ||
59 | |||
60 | /* Convert to Q10 */ | ||
61 | in32 = silk_LSHIFT( (opus_int32)in[ 2 * k + 1 ], 10 ); | ||
62 | |||
63 | /* All-pass section for odd input sample, and add to output of previous section */ | ||
64 | Y = silk_SUB32( in32, S[ 1 ] ); | ||
65 | X = silk_SMULWB( Y, silk_resampler_down2_0 ); | ||
66 | out32 = silk_ADD32( out32, S[ 1 ] ); | ||
67 | out32 = silk_ADD32( out32, X ); | ||
68 | S[ 1 ] = silk_ADD32( in32, X ); | ||
69 | |||
70 | /* Add, convert back to int16 and store to output */ | ||
71 | out[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( out32, 11 ) ); | ||
72 | } | ||
73 | } | ||
74 | |||
diff --git a/lib/rbcodec/codecs/libopus/silk/resampler_down2_3.c b/lib/rbcodec/codecs/libopus/silk/resampler_down2_3.c new file mode 100644 index 0000000000..4342614dcc --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/resampler_down2_3.c | |||
@@ -0,0 +1,103 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "SigProc_FIX.h" | ||
33 | #include "resampler_private.h" | ||
34 | #include "stack_alloc.h" | ||
35 | |||
36 | #define ORDER_FIR 4 | ||
37 | |||
38 | /* Downsample by a factor 2/3, low quality */ | ||
39 | void silk_resampler_down2_3( | ||
40 | opus_int32 *S, /* I/O State vector [ 6 ] */ | ||
41 | opus_int16 *out, /* O Output signal [ floor(2*inLen/3) ] */ | ||
42 | const opus_int16 *in, /* I Input signal [ inLen ] */ | ||
43 | opus_int32 inLen /* I Number of input samples */ | ||
44 | ) | ||
45 | { | ||
46 | opus_int32 nSamplesIn, counter, res_Q6; | ||
47 | VARDECL( opus_int32, buf ); | ||
48 | opus_int32 *buf_ptr; | ||
49 | SAVE_STACK; | ||
50 | |||
51 | ALLOC( buf, RESAMPLER_MAX_BATCH_SIZE_IN + ORDER_FIR, opus_int32 ); | ||
52 | |||
53 | /* Copy buffered samples to start of buffer */ | ||
54 | silk_memcpy( buf, S, ORDER_FIR * sizeof( opus_int32 ) ); | ||
55 | |||
56 | /* Iterate over blocks of frameSizeIn input samples */ | ||
57 | while( 1 ) { | ||
58 | nSamplesIn = silk_min( inLen, RESAMPLER_MAX_BATCH_SIZE_IN ); | ||
59 | |||
60 | /* Second-order AR filter (output in Q8) */ | ||
61 | silk_resampler_private_AR2( &S[ ORDER_FIR ], &buf[ ORDER_FIR ], in, | ||
62 | silk_Resampler_2_3_COEFS_LQ, nSamplesIn ); | ||
63 | |||
64 | /* Interpolate filtered signal */ | ||
65 | buf_ptr = buf; | ||
66 | counter = nSamplesIn; | ||
67 | while( counter > 2 ) { | ||
68 | /* Inner product */ | ||
69 | res_Q6 = silk_SMULWB( buf_ptr[ 0 ], silk_Resampler_2_3_COEFS_LQ[ 2 ] ); | ||
70 | res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 1 ], silk_Resampler_2_3_COEFS_LQ[ 3 ] ); | ||
71 | res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 2 ], silk_Resampler_2_3_COEFS_LQ[ 5 ] ); | ||
72 | res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 3 ], silk_Resampler_2_3_COEFS_LQ[ 4 ] ); | ||
73 | |||
74 | /* Scale down, saturate and store in output array */ | ||
75 | *out++ = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( res_Q6, 6 ) ); | ||
76 | |||
77 | res_Q6 = silk_SMULWB( buf_ptr[ 1 ], silk_Resampler_2_3_COEFS_LQ[ 4 ] ); | ||
78 | res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 2 ], silk_Resampler_2_3_COEFS_LQ[ 5 ] ); | ||
79 | res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 3 ], silk_Resampler_2_3_COEFS_LQ[ 3 ] ); | ||
80 | res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 4 ], silk_Resampler_2_3_COEFS_LQ[ 2 ] ); | ||
81 | |||
82 | /* Scale down, saturate and store in output array */ | ||
83 | *out++ = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( res_Q6, 6 ) ); | ||
84 | |||
85 | buf_ptr += 3; | ||
86 | counter -= 3; | ||
87 | } | ||
88 | |||
89 | in += nSamplesIn; | ||
90 | inLen -= nSamplesIn; | ||
91 | |||
92 | if( inLen > 0 ) { | ||
93 | /* More iterations to do; copy last part of filtered signal to beginning of buffer */ | ||
94 | silk_memcpy( buf, &buf[ nSamplesIn ], ORDER_FIR * sizeof( opus_int32 ) ); | ||
95 | } else { | ||
96 | break; | ||
97 | } | ||
98 | } | ||
99 | |||
100 | /* Copy last part of filtered signal to the state for the next call */ | ||
101 | silk_memcpy( S, &buf[ nSamplesIn ], ORDER_FIR * sizeof( opus_int32 ) ); | ||
102 | RESTORE_STACK; | ||
103 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/resampler_private_down_FIR.c b/lib/rbcodec/codecs/libopus/silk/resampler_private_down_FIR.c index 783e42b356..3e8735a35a 100644 --- a/lib/rbcodec/codecs/libopus/silk/resampler_private_down_FIR.c +++ b/lib/rbcodec/codecs/libopus/silk/resampler_private_down_FIR.c | |||
@@ -136,7 +136,7 @@ static OPUS_INLINE opus_int16 *silk_resampler_private_down_FIR_INTERPOL( | |||
136 | } | 136 | } |
137 | break; | 137 | break; |
138 | default: | 138 | default: |
139 | silk_assert( 0 ); | 139 | celt_assert( 0 ); |
140 | } | 140 | } |
141 | return out; | 141 | return out; |
142 | } | 142 | } |
diff --git a/lib/rbcodec/codecs/libopus/silk/resampler_rom.c b/lib/rbcodec/codecs/libopus/silk/resampler_rom.c index 2d502706f9..5e6b04476a 100644 --- a/lib/rbcodec/codecs/libopus/silk/resampler_rom.c +++ b/lib/rbcodec/codecs/libopus/silk/resampler_rom.c | |||
@@ -41,36 +41,36 @@ POSSIBILITY OF SUCH DAMAGE. | |||
41 | 41 | ||
42 | /* Tables with IIR and FIR coefficients for fractional downsamplers (123 Words) */ | 42 | /* Tables with IIR and FIR coefficients for fractional downsamplers (123 Words) */ |
43 | silk_DWORD_ALIGN const opus_int16 silk_Resampler_3_4_COEFS[ 2 + 3 * RESAMPLER_DOWN_ORDER_FIR0 / 2 ] = { | 43 | silk_DWORD_ALIGN const opus_int16 silk_Resampler_3_4_COEFS[ 2 + 3 * RESAMPLER_DOWN_ORDER_FIR0 / 2 ] = { |
44 | -20694, -13867, | 44 | -20694, -13867, |
45 | -49, 64, 17, -157, 353, -496, 163, 11047, 22205, | 45 | -49, 64, 17, -157, 353, -496, 163, 11047, 22205, |
46 | -39, 6, 91, -170, 186, 23, -896, 6336, 19928, | 46 | -39, 6, 91, -170, 186, 23, -896, 6336, 19928, |
47 | -19, -36, 102, -89, -24, 328, -951, 2568, 15909, | 47 | -19, -36, 102, -89, -24, 328, -951, 2568, 15909, |
48 | }; | 48 | }; |
49 | 49 | ||
50 | silk_DWORD_ALIGN const opus_int16 silk_Resampler_2_3_COEFS[ 2 + 2 * RESAMPLER_DOWN_ORDER_FIR0 / 2 ] = { | 50 | silk_DWORD_ALIGN const opus_int16 silk_Resampler_2_3_COEFS[ 2 + 2 * RESAMPLER_DOWN_ORDER_FIR0 / 2 ] = { |
51 | -14457, -14019, | 51 | -14457, -14019, |
52 | 64, 128, -122, 36, 310, -768, 584, 9267, 17733, | 52 | 64, 128, -122, 36, 310, -768, 584, 9267, 17733, |
53 | 12, 128, 18, -142, 288, -117, -865, 4123, 14459, | 53 | 12, 128, 18, -142, 288, -117, -865, 4123, 14459, |
54 | }; | 54 | }; |
55 | 55 | ||
56 | silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_2_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR1 / 2 ] = { | 56 | silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_2_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR1 / 2 ] = { |
57 | 616, -14323, | 57 | 616, -14323, |
58 | -10, 39, 58, -46, -84, 120, 184, -315, -541, 1284, 5380, 9024, | 58 | -10, 39, 58, -46, -84, 120, 184, -315, -541, 1284, 5380, 9024, |
59 | }; | 59 | }; |
60 | 60 | ||
61 | silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_3_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ] = { | 61 | silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_3_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ] = { |
62 | 16102, -15162, | 62 | 16102, -15162, |
63 | -13, 0, 20, 26, 5, -31, -43, -4, 65, 90, 7, -157, -248, -44, 593, 1583, 2612, 3271, | 63 | -13, 0, 20, 26, 5, -31, -43, -4, 65, 90, 7, -157, -248, -44, 593, 1583, 2612, 3271, |
64 | }; | 64 | }; |
65 | 65 | ||
66 | silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_4_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ] = { | 66 | silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_4_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ] = { |
67 | 22500, -15099, | 67 | 22500, -15099, |
68 | 3, -14, -20, -15, 2, 25, 37, 25, -16, -71, -107, -79, 50, 292, 623, 982, 1288, 1464, | 68 | 3, -14, -20, -15, 2, 25, 37, 25, -16, -71, -107, -79, 50, 292, 623, 982, 1288, 1464, |
69 | }; | 69 | }; |
70 | 70 | ||
71 | silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_6_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ] = { | 71 | silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_6_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ] = { |
72 | 27540, -15257, | 72 | 27540, -15257, |
73 | 17, 12, 8, 1, -10, -22, -30, -32, -22, 3, 44, 100, 168, 243, 317, 381, 429, 455, | 73 | 17, 12, 8, 1, -10, -22, -30, -32, -22, 3, 44, 100, 168, 243, 317, 381, 429, 455, |
74 | }; | 74 | }; |
75 | 75 | ||
76 | silk_DWORD_ALIGN const opus_int16 silk_Resampler_2_3_COEFS_LQ[ 2 + 2 * 2 ] = { | 76 | silk_DWORD_ALIGN const opus_int16 silk_Resampler_2_3_COEFS_LQ[ 2 + 2 * 2 ] = { |
@@ -81,16 +81,16 @@ silk_DWORD_ALIGN const opus_int16 silk_Resampler_2_3_COEFS_LQ[ 2 + 2 * 2 ] = { | |||
81 | 81 | ||
82 | /* Table with interplation fractions of 1/24, 3/24, 5/24, ... , 23/24 : 23/24 (46 Words) */ | 82 | /* Table with interplation fractions of 1/24, 3/24, 5/24, ... , 23/24 : 23/24 (46 Words) */ |
83 | silk_DWORD_ALIGN const opus_int16 silk_resampler_frac_FIR_12[ 12 ][ RESAMPLER_ORDER_FIR_12 / 2 ] = { | 83 | silk_DWORD_ALIGN const opus_int16 silk_resampler_frac_FIR_12[ 12 ][ RESAMPLER_ORDER_FIR_12 / 2 ] = { |
84 | { 189, -600, 617, 30567 }, | 84 | { 189, -600, 617, 30567 }, |
85 | { 117, -159, -1070, 29704 }, | 85 | { 117, -159, -1070, 29704 }, |
86 | { 52, 221, -2392, 28276 }, | 86 | { 52, 221, -2392, 28276 }, |
87 | { -4, 529, -3350, 26341 }, | 87 | { -4, 529, -3350, 26341 }, |
88 | { -48, 758, -3956, 23973 }, | 88 | { -48, 758, -3956, 23973 }, |
89 | { -80, 905, -4235, 21254 }, | 89 | { -80, 905, -4235, 21254 }, |
90 | { -99, 972, -4222, 18278 }, | 90 | { -99, 972, -4222, 18278 }, |
91 | { -107, 967, -3957, 15143 }, | 91 | { -107, 967, -3957, 15143 }, |
92 | { -103, 896, -3487, 11950 }, | 92 | { -103, 896, -3487, 11950 }, |
93 | { -91, 773, -2865, 8798 }, | 93 | { -91, 773, -2865, 8798 }, |
94 | { -71, 611, -2143, 5784 }, | 94 | { -71, 611, -2143, 5784 }, |
95 | { -46, 425, -1375, 2996 }, | 95 | { -46, 425, -1375, 2996 }, |
96 | }; | 96 | }; |
diff --git a/lib/rbcodec/codecs/libopus/silk/shell_coder.c b/lib/rbcodec/codecs/libopus/silk/shell_coder.c index d80dd51f9e..4af341474b 100644 --- a/lib/rbcodec/codecs/libopus/silk/shell_coder.c +++ b/lib/rbcodec/codecs/libopus/silk/shell_coder.c | |||
@@ -45,7 +45,6 @@ static OPUS_INLINE void combine_pulses( | |||
45 | } | 45 | } |
46 | } | 46 | } |
47 | 47 | ||
48 | #if 0 | ||
49 | static OPUS_INLINE void encode_split( | 48 | static OPUS_INLINE void encode_split( |
50 | ec_enc *psRangeEnc, /* I/O compressor data structure */ | 49 | ec_enc *psRangeEnc, /* I/O compressor data structure */ |
51 | const opus_int p_child1, /* I pulse amplitude of first child subframe */ | 50 | const opus_int p_child1, /* I pulse amplitude of first child subframe */ |
@@ -57,7 +56,6 @@ static OPUS_INLINE void encode_split( | |||
57 | ec_enc_icdf( psRangeEnc, p_child1, &shell_table[ silk_shell_code_table_offsets[ p ] ], 8 ); | 56 | ec_enc_icdf( psRangeEnc, p_child1, &shell_table[ silk_shell_code_table_offsets[ p ] ], 8 ); |
58 | } | 57 | } |
59 | } | 58 | } |
60 | #endif | ||
61 | 59 | ||
62 | static OPUS_INLINE void decode_split( | 60 | static OPUS_INLINE void decode_split( |
63 | opus_int16 *p_child1, /* O pulse amplitude of first child subframe */ | 61 | opus_int16 *p_child1, /* O pulse amplitude of first child subframe */ |
@@ -76,7 +74,6 @@ static OPUS_INLINE void decode_split( | |||
76 | } | 74 | } |
77 | } | 75 | } |
78 | 76 | ||
79 | #if 0 | ||
80 | /* Shell encoder, operates on one shell code frame of 16 pulses */ | 77 | /* Shell encoder, operates on one shell code frame of 16 pulses */ |
81 | void silk_shell_encoder( | 78 | void silk_shell_encoder( |
82 | ec_enc *psRangeEnc, /* I/O compressor data structure */ | 79 | ec_enc *psRangeEnc, /* I/O compressor data structure */ |
@@ -116,7 +113,6 @@ void silk_shell_encoder( | |||
116 | encode_split( psRangeEnc, pulses0[ 12 ], pulses1[ 6 ], silk_shell_code_table0 ); | 113 | encode_split( psRangeEnc, pulses0[ 12 ], pulses1[ 6 ], silk_shell_code_table0 ); |
117 | encode_split( psRangeEnc, pulses0[ 14 ], pulses1[ 7 ], silk_shell_code_table0 ); | 114 | encode_split( psRangeEnc, pulses0[ 14 ], pulses1[ 7 ], silk_shell_code_table0 ); |
118 | } | 115 | } |
119 | #endif | ||
120 | 116 | ||
121 | 117 | ||
122 | /* Shell decoder, operates on one shell code frame of 16 pulses */ | 118 | /* Shell decoder, operates on one shell code frame of 16 pulses */ |
diff --git a/lib/rbcodec/codecs/libopus/silk/sigm_Q15.c b/lib/rbcodec/codecs/libopus/silk/sigm_Q15.c new file mode 100644 index 0000000000..3c507d255b --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/sigm_Q15.c | |||
@@ -0,0 +1,76 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | /* Approximate sigmoid function */ | ||
33 | |||
34 | #include "SigProc_FIX.h" | ||
35 | |||
36 | /* fprintf(1, '%d, ', round(1024 * ([1 ./ (1 + exp(-(1:5))), 1] - 1 ./ (1 + exp(-(0:5)))))); */ | ||
37 | static const opus_int32 sigm_LUT_slope_Q10[ 6 ] = { | ||
38 | 237, 153, 73, 30, 12, 7 | ||
39 | }; | ||
40 | /* fprintf(1, '%d, ', round(32767 * 1 ./ (1 + exp(-(0:5))))); */ | ||
41 | static const opus_int32 sigm_LUT_pos_Q15[ 6 ] = { | ||
42 | 16384, 23955, 28861, 31213, 32178, 32548 | ||
43 | }; | ||
44 | /* fprintf(1, '%d, ', round(32767 * 1 ./ (1 + exp((0:5))))); */ | ||
45 | static const opus_int32 sigm_LUT_neg_Q15[ 6 ] = { | ||
46 | 16384, 8812, 3906, 1554, 589, 219 | ||
47 | }; | ||
48 | |||
49 | opus_int silk_sigm_Q15( | ||
50 | opus_int in_Q5 /* I */ | ||
51 | ) | ||
52 | { | ||
53 | opus_int ind; | ||
54 | |||
55 | if( in_Q5 < 0 ) { | ||
56 | /* Negative input */ | ||
57 | in_Q5 = -in_Q5; | ||
58 | if( in_Q5 >= 6 * 32 ) { | ||
59 | return 0; /* Clip */ | ||
60 | } else { | ||
61 | /* Linear interpolation of look up table */ | ||
62 | ind = silk_RSHIFT( in_Q5, 5 ); | ||
63 | return( sigm_LUT_neg_Q15[ ind ] - silk_SMULBB( sigm_LUT_slope_Q10[ ind ], in_Q5 & 0x1F ) ); | ||
64 | } | ||
65 | } else { | ||
66 | /* Positive input */ | ||
67 | if( in_Q5 >= 6 * 32 ) { | ||
68 | return 32767; /* clip */ | ||
69 | } else { | ||
70 | /* Linear interpolation of look up table */ | ||
71 | ind = silk_RSHIFT( in_Q5, 5 ); | ||
72 | return( sigm_LUT_pos_Q15[ ind ] + silk_SMULBB( sigm_LUT_slope_Q10[ ind ], in_Q5 & 0x1F ) ); | ||
73 | } | ||
74 | } | ||
75 | } | ||
76 | |||
diff --git a/lib/rbcodec/codecs/libopus/silk/sort.c b/lib/rbcodec/codecs/libopus/silk/sort.c index 2f9930d9ce..4fba16f831 100644 --- a/lib/rbcodec/codecs/libopus/silk/sort.c +++ b/lib/rbcodec/codecs/libopus/silk/sort.c | |||
@@ -33,11 +33,10 @@ POSSIBILITY OF SUCH DAMAGE. | |||
33 | /* Best case: O(n) for an already sorted array */ | 33 | /* Best case: O(n) for an already sorted array */ |
34 | /* Worst case: O(n^2) for an inversely sorted array */ | 34 | /* Worst case: O(n^2) for an inversely sorted array */ |
35 | /* */ | 35 | /* */ |
36 | /* Shell short: http://en.wikipedia.org/wiki/Shell_sort */ | 36 | /* Shell short: https://en.wikipedia.org/wiki/Shell_sort */ |
37 | 37 | ||
38 | #include "SigProc_FIX.h" | 38 | #include "SigProc_FIX.h" |
39 | 39 | ||
40 | #if 0 | ||
41 | void silk_insertion_sort_increasing( | 40 | void silk_insertion_sort_increasing( |
42 | opus_int32 *a, /* I/O Unsorted / Sorted vector */ | 41 | opus_int32 *a, /* I/O Unsorted / Sorted vector */ |
43 | opus_int *idx, /* O Index vector for the sorted elements */ | 42 | opus_int *idx, /* O Index vector for the sorted elements */ |
@@ -49,9 +48,9 @@ void silk_insertion_sort_increasing( | |||
49 | opus_int i, j; | 48 | opus_int i, j; |
50 | 49 | ||
51 | /* Safety checks */ | 50 | /* Safety checks */ |
52 | silk_assert( K > 0 ); | 51 | celt_assert( K > 0 ); |
53 | silk_assert( L > 0 ); | 52 | celt_assert( L > 0 ); |
54 | silk_assert( L >= K ); | 53 | celt_assert( L >= K ); |
55 | 54 | ||
56 | /* Write start indices in index vector */ | 55 | /* Write start indices in index vector */ |
57 | for( i = 0; i < K; i++ ) { | 56 | for( i = 0; i < K; i++ ) { |
@@ -83,7 +82,6 @@ void silk_insertion_sort_increasing( | |||
83 | } | 82 | } |
84 | } | 83 | } |
85 | } | 84 | } |
86 | #endif | ||
87 | 85 | ||
88 | #ifdef FIXED_POINT | 86 | #ifdef FIXED_POINT |
89 | /* This function is only used by the fixed-point build */ | 87 | /* This function is only used by the fixed-point build */ |
@@ -98,9 +96,9 @@ void silk_insertion_sort_decreasing_int16( | |||
98 | opus_int value; | 96 | opus_int value; |
99 | 97 | ||
100 | /* Safety checks */ | 98 | /* Safety checks */ |
101 | silk_assert( K > 0 ); | 99 | celt_assert( K > 0 ); |
102 | silk_assert( L > 0 ); | 100 | celt_assert( L > 0 ); |
103 | silk_assert( L >= K ); | 101 | celt_assert( L >= K ); |
104 | 102 | ||
105 | /* Write start indices in index vector */ | 103 | /* Write start indices in index vector */ |
106 | for( i = 0; i < K; i++ ) { | 104 | for( i = 0; i < K; i++ ) { |
@@ -143,7 +141,7 @@ void silk_insertion_sort_increasing_all_values_int16( | |||
143 | opus_int i, j; | 141 | opus_int i, j; |
144 | 142 | ||
145 | /* Safety checks */ | 143 | /* Safety checks */ |
146 | silk_assert( L > 0 ); | 144 | celt_assert( L > 0 ); |
147 | 145 | ||
148 | /* Sort vector elements by value, increasing order */ | 146 | /* Sort vector elements by value, increasing order */ |
149 | for( i = 1; i < L; i++ ) { | 147 | for( i = 1; i < L; i++ ) { |
diff --git a/lib/rbcodec/codecs/libopus/silk/stereo_LR_to_MS.c b/lib/rbcodec/codecs/libopus/silk/stereo_LR_to_MS.c new file mode 100644 index 0000000000..c8226663c8 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/stereo_LR_to_MS.c | |||
@@ -0,0 +1,229 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main.h" | ||
33 | #include "stack_alloc.h" | ||
34 | |||
35 | /* Convert Left/Right stereo signal to adaptive Mid/Side representation */ | ||
36 | void silk_stereo_LR_to_MS( | ||
37 | stereo_enc_state *state, /* I/O State */ | ||
38 | opus_int16 x1[], /* I/O Left input signal, becomes mid signal */ | ||
39 | opus_int16 x2[], /* I/O Right input signal, becomes side signal */ | ||
40 | opus_int8 ix[ 2 ][ 3 ], /* O Quantization indices */ | ||
41 | opus_int8 *mid_only_flag, /* O Flag: only mid signal coded */ | ||
42 | opus_int32 mid_side_rates_bps[], /* O Bitrates for mid and side signals */ | ||
43 | opus_int32 total_rate_bps, /* I Total bitrate */ | ||
44 | opus_int prev_speech_act_Q8, /* I Speech activity level in previous frame */ | ||
45 | opus_int toMono, /* I Last frame before a stereo->mono transition */ | ||
46 | opus_int fs_kHz, /* I Sample rate (kHz) */ | ||
47 | opus_int frame_length /* I Number of samples */ | ||
48 | ) | ||
49 | { | ||
50 | opus_int n, is10msFrame, denom_Q16, delta0_Q13, delta1_Q13; | ||
51 | opus_int32 sum, diff, smooth_coef_Q16, pred_Q13[ 2 ], pred0_Q13, pred1_Q13; | ||
52 | opus_int32 LP_ratio_Q14, HP_ratio_Q14, frac_Q16, frac_3_Q16, min_mid_rate_bps, width_Q14, w_Q24, deltaw_Q24; | ||
53 | VARDECL( opus_int16, side ); | ||
54 | VARDECL( opus_int16, LP_mid ); | ||
55 | VARDECL( opus_int16, HP_mid ); | ||
56 | VARDECL( opus_int16, LP_side ); | ||
57 | VARDECL( opus_int16, HP_side ); | ||
58 | opus_int16 *mid = &x1[ -2 ]; | ||
59 | SAVE_STACK; | ||
60 | |||
61 | ALLOC( side, frame_length + 2, opus_int16 ); | ||
62 | /* Convert to basic mid/side signals */ | ||
63 | for( n = 0; n < frame_length + 2; n++ ) { | ||
64 | sum = x1[ n - 2 ] + (opus_int32)x2[ n - 2 ]; | ||
65 | diff = x1[ n - 2 ] - (opus_int32)x2[ n - 2 ]; | ||
66 | mid[ n ] = (opus_int16)silk_RSHIFT_ROUND( sum, 1 ); | ||
67 | side[ n ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( diff, 1 ) ); | ||
68 | } | ||
69 | |||
70 | /* Buffering */ | ||
71 | silk_memcpy( mid, state->sMid, 2 * sizeof( opus_int16 ) ); | ||
72 | silk_memcpy( side, state->sSide, 2 * sizeof( opus_int16 ) ); | ||
73 | silk_memcpy( state->sMid, &mid[ frame_length ], 2 * sizeof( opus_int16 ) ); | ||
74 | silk_memcpy( state->sSide, &side[ frame_length ], 2 * sizeof( opus_int16 ) ); | ||
75 | |||
76 | /* LP and HP filter mid signal */ | ||
77 | ALLOC( LP_mid, frame_length, opus_int16 ); | ||
78 | ALLOC( HP_mid, frame_length, opus_int16 ); | ||
79 | for( n = 0; n < frame_length; n++ ) { | ||
80 | sum = silk_RSHIFT_ROUND( silk_ADD_LSHIFT( mid[ n ] + (opus_int32)mid[ n + 2 ], mid[ n + 1 ], 1 ), 2 ); | ||
81 | LP_mid[ n ] = sum; | ||
82 | HP_mid[ n ] = mid[ n + 1 ] - sum; | ||
83 | } | ||
84 | |||
85 | /* LP and HP filter side signal */ | ||
86 | ALLOC( LP_side, frame_length, opus_int16 ); | ||
87 | ALLOC( HP_side, frame_length, opus_int16 ); | ||
88 | for( n = 0; n < frame_length; n++ ) { | ||
89 | sum = silk_RSHIFT_ROUND( silk_ADD_LSHIFT( side[ n ] + (opus_int32)side[ n + 2 ], side[ n + 1 ], 1 ), 2 ); | ||
90 | LP_side[ n ] = sum; | ||
91 | HP_side[ n ] = side[ n + 1 ] - sum; | ||
92 | } | ||
93 | |||
94 | /* Find energies and predictors */ | ||
95 | is10msFrame = frame_length == 10 * fs_kHz; | ||
96 | smooth_coef_Q16 = is10msFrame ? | ||
97 | SILK_FIX_CONST( STEREO_RATIO_SMOOTH_COEF / 2, 16 ) : | ||
98 | SILK_FIX_CONST( STEREO_RATIO_SMOOTH_COEF, 16 ); | ||
99 | smooth_coef_Q16 = silk_SMULWB( silk_SMULBB( prev_speech_act_Q8, prev_speech_act_Q8 ), smooth_coef_Q16 ); | ||
100 | |||
101 | pred_Q13[ 0 ] = silk_stereo_find_predictor( &LP_ratio_Q14, LP_mid, LP_side, &state->mid_side_amp_Q0[ 0 ], frame_length, smooth_coef_Q16 ); | ||
102 | pred_Q13[ 1 ] = silk_stereo_find_predictor( &HP_ratio_Q14, HP_mid, HP_side, &state->mid_side_amp_Q0[ 2 ], frame_length, smooth_coef_Q16 ); | ||
103 | /* Ratio of the norms of residual and mid signals */ | ||
104 | frac_Q16 = silk_SMLABB( HP_ratio_Q14, LP_ratio_Q14, 3 ); | ||
105 | frac_Q16 = silk_min( frac_Q16, SILK_FIX_CONST( 1, 16 ) ); | ||
106 | |||
107 | /* Determine bitrate distribution between mid and side, and possibly reduce stereo width */ | ||
108 | total_rate_bps -= is10msFrame ? 1200 : 600; /* Subtract approximate bitrate for coding stereo parameters */ | ||
109 | if( total_rate_bps < 1 ) { | ||
110 | total_rate_bps = 1; | ||
111 | } | ||
112 | min_mid_rate_bps = silk_SMLABB( 2000, fs_kHz, 600 ); | ||
113 | silk_assert( min_mid_rate_bps < 32767 ); | ||
114 | /* Default bitrate distribution: 8 parts for Mid and (5+3*frac) parts for Side. so: mid_rate = ( 8 / ( 13 + 3 * frac ) ) * total_ rate */ | ||
115 | frac_3_Q16 = silk_MUL( 3, frac_Q16 ); | ||
116 | mid_side_rates_bps[ 0 ] = silk_DIV32_varQ( total_rate_bps, SILK_FIX_CONST( 8 + 5, 16 ) + frac_3_Q16, 16+3 ); | ||
117 | /* If Mid bitrate below minimum, reduce stereo width */ | ||
118 | if( mid_side_rates_bps[ 0 ] < min_mid_rate_bps ) { | ||
119 | mid_side_rates_bps[ 0 ] = min_mid_rate_bps; | ||
120 | mid_side_rates_bps[ 1 ] = total_rate_bps - mid_side_rates_bps[ 0 ]; | ||
121 | /* width = 4 * ( 2 * side_rate - min_rate ) / ( ( 1 + 3 * frac ) * min_rate ) */ | ||
122 | width_Q14 = silk_DIV32_varQ( silk_LSHIFT( mid_side_rates_bps[ 1 ], 1 ) - min_mid_rate_bps, | ||
123 | silk_SMULWB( SILK_FIX_CONST( 1, 16 ) + frac_3_Q16, min_mid_rate_bps ), 14+2 ); | ||
124 | width_Q14 = silk_LIMIT( width_Q14, 0, SILK_FIX_CONST( 1, 14 ) ); | ||
125 | } else { | ||
126 | mid_side_rates_bps[ 1 ] = total_rate_bps - mid_side_rates_bps[ 0 ]; | ||
127 | width_Q14 = SILK_FIX_CONST( 1, 14 ); | ||
128 | } | ||
129 | |||
130 | /* Smoother */ | ||
131 | state->smth_width_Q14 = (opus_int16)silk_SMLAWB( state->smth_width_Q14, width_Q14 - state->smth_width_Q14, smooth_coef_Q16 ); | ||
132 | |||
133 | /* At very low bitrates or for inputs that are nearly amplitude panned, switch to panned-mono coding */ | ||
134 | *mid_only_flag = 0; | ||
135 | if( toMono ) { | ||
136 | /* Last frame before stereo->mono transition; collapse stereo width */ | ||
137 | width_Q14 = 0; | ||
138 | pred_Q13[ 0 ] = 0; | ||
139 | pred_Q13[ 1 ] = 0; | ||
140 | silk_stereo_quant_pred( pred_Q13, ix ); | ||
141 | } else if( state->width_prev_Q14 == 0 && | ||
142 | ( 8 * total_rate_bps < 13 * min_mid_rate_bps || silk_SMULWB( frac_Q16, state->smth_width_Q14 ) < SILK_FIX_CONST( 0.05, 14 ) ) ) | ||
143 | { | ||
144 | /* Code as panned-mono; previous frame already had zero width */ | ||
145 | /* Scale down and quantize predictors */ | ||
146 | pred_Q13[ 0 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 0 ] ), 14 ); | ||
147 | pred_Q13[ 1 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 1 ] ), 14 ); | ||
148 | silk_stereo_quant_pred( pred_Q13, ix ); | ||
149 | /* Collapse stereo width */ | ||
150 | width_Q14 = 0; | ||
151 | pred_Q13[ 0 ] = 0; | ||
152 | pred_Q13[ 1 ] = 0; | ||
153 | mid_side_rates_bps[ 0 ] = total_rate_bps; | ||
154 | mid_side_rates_bps[ 1 ] = 0; | ||
155 | *mid_only_flag = 1; | ||
156 | } else if( state->width_prev_Q14 != 0 && | ||
157 | ( 8 * total_rate_bps < 11 * min_mid_rate_bps || silk_SMULWB( frac_Q16, state->smth_width_Q14 ) < SILK_FIX_CONST( 0.02, 14 ) ) ) | ||
158 | { | ||
159 | /* Transition to zero-width stereo */ | ||
160 | /* Scale down and quantize predictors */ | ||
161 | pred_Q13[ 0 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 0 ] ), 14 ); | ||
162 | pred_Q13[ 1 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 1 ] ), 14 ); | ||
163 | silk_stereo_quant_pred( pred_Q13, ix ); | ||
164 | /* Collapse stereo width */ | ||
165 | width_Q14 = 0; | ||
166 | pred_Q13[ 0 ] = 0; | ||
167 | pred_Q13[ 1 ] = 0; | ||
168 | } else if( state->smth_width_Q14 > SILK_FIX_CONST( 0.95, 14 ) ) { | ||
169 | /* Full-width stereo coding */ | ||
170 | silk_stereo_quant_pred( pred_Q13, ix ); | ||
171 | width_Q14 = SILK_FIX_CONST( 1, 14 ); | ||
172 | } else { | ||
173 | /* Reduced-width stereo coding; scale down and quantize predictors */ | ||
174 | pred_Q13[ 0 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 0 ] ), 14 ); | ||
175 | pred_Q13[ 1 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 1 ] ), 14 ); | ||
176 | silk_stereo_quant_pred( pred_Q13, ix ); | ||
177 | width_Q14 = state->smth_width_Q14; | ||
178 | } | ||
179 | |||
180 | /* Make sure to keep on encoding until the tapered output has been transmitted */ | ||
181 | if( *mid_only_flag == 1 ) { | ||
182 | state->silent_side_len += frame_length - STEREO_INTERP_LEN_MS * fs_kHz; | ||
183 | if( state->silent_side_len < LA_SHAPE_MS * fs_kHz ) { | ||
184 | *mid_only_flag = 0; | ||
185 | } else { | ||
186 | /* Limit to avoid wrapping around */ | ||
187 | state->silent_side_len = 10000; | ||
188 | } | ||
189 | } else { | ||
190 | state->silent_side_len = 0; | ||
191 | } | ||
192 | |||
193 | if( *mid_only_flag == 0 && mid_side_rates_bps[ 1 ] < 1 ) { | ||
194 | mid_side_rates_bps[ 1 ] = 1; | ||
195 | mid_side_rates_bps[ 0 ] = silk_max_int( 1, total_rate_bps - mid_side_rates_bps[ 1 ]); | ||
196 | } | ||
197 | |||
198 | /* Interpolate predictors and subtract prediction from side channel */ | ||
199 | pred0_Q13 = -state->pred_prev_Q13[ 0 ]; | ||
200 | pred1_Q13 = -state->pred_prev_Q13[ 1 ]; | ||
201 | w_Q24 = silk_LSHIFT( state->width_prev_Q14, 10 ); | ||
202 | denom_Q16 = silk_DIV32_16( (opus_int32)1 << 16, STEREO_INTERP_LEN_MS * fs_kHz ); | ||
203 | delta0_Q13 = -silk_RSHIFT_ROUND( silk_SMULBB( pred_Q13[ 0 ] - state->pred_prev_Q13[ 0 ], denom_Q16 ), 16 ); | ||
204 | delta1_Q13 = -silk_RSHIFT_ROUND( silk_SMULBB( pred_Q13[ 1 ] - state->pred_prev_Q13[ 1 ], denom_Q16 ), 16 ); | ||
205 | deltaw_Q24 = silk_LSHIFT( silk_SMULWB( width_Q14 - state->width_prev_Q14, denom_Q16 ), 10 ); | ||
206 | for( n = 0; n < STEREO_INTERP_LEN_MS * fs_kHz; n++ ) { | ||
207 | pred0_Q13 += delta0_Q13; | ||
208 | pred1_Q13 += delta1_Q13; | ||
209 | w_Q24 += deltaw_Q24; | ||
210 | sum = silk_LSHIFT( silk_ADD_LSHIFT( mid[ n ] + (opus_int32)mid[ n + 2 ], mid[ n + 1 ], 1 ), 9 ); /* Q11 */ | ||
211 | sum = silk_SMLAWB( silk_SMULWB( w_Q24, side[ n + 1 ] ), sum, pred0_Q13 ); /* Q8 */ | ||
212 | sum = silk_SMLAWB( sum, silk_LSHIFT( (opus_int32)mid[ n + 1 ], 11 ), pred1_Q13 ); /* Q8 */ | ||
213 | x2[ n - 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) ); | ||
214 | } | ||
215 | |||
216 | pred0_Q13 = -pred_Q13[ 0 ]; | ||
217 | pred1_Q13 = -pred_Q13[ 1 ]; | ||
218 | w_Q24 = silk_LSHIFT( width_Q14, 10 ); | ||
219 | for( n = STEREO_INTERP_LEN_MS * fs_kHz; n < frame_length; n++ ) { | ||
220 | sum = silk_LSHIFT( silk_ADD_LSHIFT( mid[ n ] + (opus_int32)mid[ n + 2 ], mid[ n + 1 ], 1 ), 9 ); /* Q11 */ | ||
221 | sum = silk_SMLAWB( silk_SMULWB( w_Q24, side[ n + 1 ] ), sum, pred0_Q13 ); /* Q8 */ | ||
222 | sum = silk_SMLAWB( sum, silk_LSHIFT( (opus_int32)mid[ n + 1 ], 11 ), pred1_Q13 ); /* Q8 */ | ||
223 | x2[ n - 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) ); | ||
224 | } | ||
225 | state->pred_prev_Q13[ 0 ] = (opus_int16)pred_Q13[ 0 ]; | ||
226 | state->pred_prev_Q13[ 1 ] = (opus_int16)pred_Q13[ 1 ]; | ||
227 | state->width_prev_Q14 = (opus_int16)width_Q14; | ||
228 | RESTORE_STACK; | ||
229 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/stereo_encode_pred.c b/lib/rbcodec/codecs/libopus/silk/stereo_encode_pred.c new file mode 100644 index 0000000000..03becb6736 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/stereo_encode_pred.c | |||
@@ -0,0 +1,62 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main.h" | ||
33 | |||
34 | /* Entropy code the mid/side quantization indices */ | ||
35 | void silk_stereo_encode_pred( | ||
36 | ec_enc *psRangeEnc, /* I/O Compressor data structure */ | ||
37 | opus_int8 ix[ 2 ][ 3 ] /* I Quantization indices */ | ||
38 | ) | ||
39 | { | ||
40 | opus_int n; | ||
41 | |||
42 | /* Entropy coding */ | ||
43 | n = 5 * ix[ 0 ][ 2 ] + ix[ 1 ][ 2 ]; | ||
44 | celt_assert( n < 25 ); | ||
45 | ec_enc_icdf( psRangeEnc, n, silk_stereo_pred_joint_iCDF, 8 ); | ||
46 | for( n = 0; n < 2; n++ ) { | ||
47 | celt_assert( ix[ n ][ 0 ] < 3 ); | ||
48 | celt_assert( ix[ n ][ 1 ] < STEREO_QUANT_SUB_STEPS ); | ||
49 | ec_enc_icdf( psRangeEnc, ix[ n ][ 0 ], silk_uniform3_iCDF, 8 ); | ||
50 | ec_enc_icdf( psRangeEnc, ix[ n ][ 1 ], silk_uniform5_iCDF, 8 ); | ||
51 | } | ||
52 | } | ||
53 | |||
54 | /* Entropy code the mid-only flag */ | ||
55 | void silk_stereo_encode_mid_only( | ||
56 | ec_enc *psRangeEnc, /* I/O Compressor data structure */ | ||
57 | opus_int8 mid_only_flag | ||
58 | ) | ||
59 | { | ||
60 | /* Encode flag that only mid channel is coded */ | ||
61 | ec_enc_icdf( psRangeEnc, mid_only_flag, silk_stereo_only_code_mid_iCDF, 8 ); | ||
62 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/stereo_find_predictor.c b/lib/rbcodec/codecs/libopus/silk/stereo_find_predictor.c new file mode 100644 index 0000000000..e30e90bddc --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/stereo_find_predictor.c | |||
@@ -0,0 +1,79 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main.h" | ||
33 | |||
34 | /* Find least-squares prediction gain for one signal based on another and quantize it */ | ||
35 | opus_int32 silk_stereo_find_predictor( /* O Returns predictor in Q13 */ | ||
36 | opus_int32 *ratio_Q14, /* O Ratio of residual and mid energies */ | ||
37 | const opus_int16 x[], /* I Basis signal */ | ||
38 | const opus_int16 y[], /* I Target signal */ | ||
39 | opus_int32 mid_res_amp_Q0[], /* I/O Smoothed mid, residual norms */ | ||
40 | opus_int length, /* I Number of samples */ | ||
41 | opus_int smooth_coef_Q16 /* I Smoothing coefficient */ | ||
42 | ) | ||
43 | { | ||
44 | opus_int scale, scale1, scale2; | ||
45 | opus_int32 nrgx, nrgy, corr, pred_Q13, pred2_Q10; | ||
46 | |||
47 | /* Find predictor */ | ||
48 | silk_sum_sqr_shift( &nrgx, &scale1, x, length ); | ||
49 | silk_sum_sqr_shift( &nrgy, &scale2, y, length ); | ||
50 | scale = silk_max_int( scale1, scale2 ); | ||
51 | scale = scale + ( scale & 1 ); /* make even */ | ||
52 | nrgy = silk_RSHIFT32( nrgy, scale - scale2 ); | ||
53 | nrgx = silk_RSHIFT32( nrgx, scale - scale1 ); | ||
54 | nrgx = silk_max_int( nrgx, 1 ); | ||
55 | corr = silk_inner_prod_aligned_scale( x, y, scale, length ); | ||
56 | pred_Q13 = silk_DIV32_varQ( corr, nrgx, 13 ); | ||
57 | pred_Q13 = silk_LIMIT( pred_Q13, -(1 << 14), 1 << 14 ); | ||
58 | pred2_Q10 = silk_SMULWB( pred_Q13, pred_Q13 ); | ||
59 | |||
60 | /* Faster update for signals with large prediction parameters */ | ||
61 | smooth_coef_Q16 = (opus_int)silk_max_int( smooth_coef_Q16, silk_abs( pred2_Q10 ) ); | ||
62 | |||
63 | /* Smoothed mid and residual norms */ | ||
64 | silk_assert( smooth_coef_Q16 < 32768 ); | ||
65 | scale = silk_RSHIFT( scale, 1 ); | ||
66 | mid_res_amp_Q0[ 0 ] = silk_SMLAWB( mid_res_amp_Q0[ 0 ], silk_LSHIFT( silk_SQRT_APPROX( nrgx ), scale ) - mid_res_amp_Q0[ 0 ], | ||
67 | smooth_coef_Q16 ); | ||
68 | /* Residual energy = nrgy - 2 * pred * corr + pred^2 * nrgx */ | ||
69 | nrgy = silk_SUB_LSHIFT32( nrgy, silk_SMULWB( corr, pred_Q13 ), 3 + 1 ); | ||
70 | nrgy = silk_ADD_LSHIFT32( nrgy, silk_SMULWB( nrgx, pred2_Q10 ), 6 ); | ||
71 | mid_res_amp_Q0[ 1 ] = silk_SMLAWB( mid_res_amp_Q0[ 1 ], silk_LSHIFT( silk_SQRT_APPROX( nrgy ), scale ) - mid_res_amp_Q0[ 1 ], | ||
72 | smooth_coef_Q16 ); | ||
73 | |||
74 | /* Ratio of smoothed residual and mid norms */ | ||
75 | *ratio_Q14 = silk_DIV32_varQ( mid_res_amp_Q0[ 1 ], silk_max( mid_res_amp_Q0[ 0 ], 1 ), 14 ); | ||
76 | *ratio_Q14 = silk_LIMIT( *ratio_Q14, 0, 32767 ); | ||
77 | |||
78 | return pred_Q13; | ||
79 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/stereo_quant_pred.c b/lib/rbcodec/codecs/libopus/silk/stereo_quant_pred.c new file mode 100644 index 0000000000..d4ced6c3e8 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/stereo_quant_pred.c | |||
@@ -0,0 +1,73 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "main.h" | ||
33 | |||
34 | /* Quantize mid/side predictors */ | ||
35 | void silk_stereo_quant_pred( | ||
36 | opus_int32 pred_Q13[], /* I/O Predictors (out: quantized) */ | ||
37 | opus_int8 ix[ 2 ][ 3 ] /* O Quantization indices */ | ||
38 | ) | ||
39 | { | ||
40 | opus_int i, j, n; | ||
41 | opus_int32 low_Q13, step_Q13, lvl_Q13, err_min_Q13, err_Q13, quant_pred_Q13 = 0; | ||
42 | |||
43 | /* Quantize */ | ||
44 | for( n = 0; n < 2; n++ ) { | ||
45 | /* Brute-force search over quantization levels */ | ||
46 | err_min_Q13 = silk_int32_MAX; | ||
47 | for( i = 0; i < STEREO_QUANT_TAB_SIZE - 1; i++ ) { | ||
48 | low_Q13 = silk_stereo_pred_quant_Q13[ i ]; | ||
49 | step_Q13 = silk_SMULWB( silk_stereo_pred_quant_Q13[ i + 1 ] - low_Q13, | ||
50 | SILK_FIX_CONST( 0.5 / STEREO_QUANT_SUB_STEPS, 16 ) ); | ||
51 | for( j = 0; j < STEREO_QUANT_SUB_STEPS; j++ ) { | ||
52 | lvl_Q13 = silk_SMLABB( low_Q13, step_Q13, 2 * j + 1 ); | ||
53 | err_Q13 = silk_abs( pred_Q13[ n ] - lvl_Q13 ); | ||
54 | if( err_Q13 < err_min_Q13 ) { | ||
55 | err_min_Q13 = err_Q13; | ||
56 | quant_pred_Q13 = lvl_Q13; | ||
57 | ix[ n ][ 0 ] = i; | ||
58 | ix[ n ][ 1 ] = j; | ||
59 | } else { | ||
60 | /* Error increasing, so we're past the optimum */ | ||
61 | goto done; | ||
62 | } | ||
63 | } | ||
64 | } | ||
65 | done: | ||
66 | ix[ n ][ 2 ] = silk_DIV32_16( ix[ n ][ 0 ], 3 ); | ||
67 | ix[ n ][ 0 ] -= ix[ n ][ 2 ] * 3; | ||
68 | pred_Q13[ n ] = quant_pred_Q13; | ||
69 | } | ||
70 | |||
71 | /* Subtract second from first predictor (helps when actually applying these) */ | ||
72 | pred_Q13[ 0 ] -= pred_Q13[ 1 ]; | ||
73 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/structs.h b/lib/rbcodec/codecs/libopus/silk/structs.h index 1826b36a80..3380c757b2 100644 --- a/lib/rbcodec/codecs/libopus/silk/structs.h +++ b/lib/rbcodec/codecs/libopus/silk/structs.h | |||
@@ -48,6 +48,7 @@ typedef struct { | |||
48 | opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH ]; | 48 | opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH ]; |
49 | opus_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ]; | 49 | opus_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ]; |
50 | opus_int32 sLF_AR_shp_Q14; | 50 | opus_int32 sLF_AR_shp_Q14; |
51 | opus_int32 sDiff_shp_Q14; | ||
51 | opus_int lagPrev; | 52 | opus_int lagPrev; |
52 | opus_int sLTP_buf_idx; | 53 | opus_int sLTP_buf_idx; |
53 | opus_int sLTP_shp_buf_idx; | 54 | opus_int sLTP_shp_buf_idx; |
@@ -77,6 +78,7 @@ typedef struct { | |||
77 | opus_int32 In_LP_State[ 2 ]; /* Low pass filter state */ | 78 | opus_int32 In_LP_State[ 2 ]; /* Low pass filter state */ |
78 | opus_int32 transition_frame_no; /* Counter which is mapped to a cut-off frequency */ | 79 | opus_int32 transition_frame_no; /* Counter which is mapped to a cut-off frequency */ |
79 | opus_int mode; /* Operating mode, <0: switch down, >0: switch up; 0: do nothing */ | 80 | opus_int mode; /* Operating mode, <0: switch down, >0: switch up; 0: do nothing */ |
81 | opus_int32 saved_fs_kHz; /* If non-zero, holds the last sampling rate before a bandwidth switching reset. */ | ||
80 | } silk_LP_state; | 82 | } silk_LP_state; |
81 | 83 | ||
82 | /* Structure containing NLSF codebook */ | 84 | /* Structure containing NLSF codebook */ |
@@ -86,6 +88,7 @@ typedef struct { | |||
86 | const opus_int16 quantStepSize_Q16; | 88 | const opus_int16 quantStepSize_Q16; |
87 | const opus_int16 invQuantStepSize_Q6; | 89 | const opus_int16 invQuantStepSize_Q6; |
88 | const opus_uint8 *CB1_NLSF_Q8; | 90 | const opus_uint8 *CB1_NLSF_Q8; |
91 | const opus_int16 *CB1_Wght_Q9; | ||
89 | const opus_uint8 *CB1_iCDF; | 92 | const opus_uint8 *CB1_iCDF; |
90 | const opus_uint8 *pred_Q8; | 93 | const opus_uint8 *pred_Q8; |
91 | const opus_uint8 *ec_sel; | 94 | const opus_uint8 *ec_sel; |
@@ -169,9 +172,7 @@ typedef struct { | |||
169 | opus_int pitchEstimationComplexity; /* Complexity level for pitch estimator */ | 172 | opus_int pitchEstimationComplexity; /* Complexity level for pitch estimator */ |
170 | opus_int pitchEstimationLPCOrder; /* Whitening filter order for pitch estimator */ | 173 | opus_int pitchEstimationLPCOrder; /* Whitening filter order for pitch estimator */ |
171 | opus_int32 pitchEstimationThreshold_Q16; /* Threshold for pitch estimator */ | 174 | opus_int32 pitchEstimationThreshold_Q16; /* Threshold for pitch estimator */ |
172 | opus_int LTPQuantLowComplexity; /* Flag for low complexity LTP quantization */ | 175 | opus_int32 sum_log_gain_Q7; /* Cumulative max prediction gain */ |
173 | opus_int mu_LTP_Q9; /* Rate-distortion tradeoff in LTP quantization */ | ||
174 | opus_int32 sum_log_gain_Q7; /* Cumulative max prediction gain */ | ||
175 | opus_int NLSF_MSVQ_Survivors; /* Number of survivors in NLSF MSVQ */ | 176 | opus_int NLSF_MSVQ_Survivors; /* Number of survivors in NLSF MSVQ */ |
176 | opus_int first_frame_after_reset; /* Flag for deactivating NLSF interpolation, pitch prediction */ | 177 | opus_int first_frame_after_reset; /* Flag for deactivating NLSF interpolation, pitch prediction */ |
177 | opus_int controlled_since_last_payload; /* Flag for ensuring codec_control only runs once per packet */ | 178 | opus_int controlled_since_last_payload; /* Flag for ensuring codec_control only runs once per packet */ |
@@ -301,6 +302,7 @@ typedef struct { | |||
301 | /* Stuff used for PLC */ | 302 | /* Stuff used for PLC */ |
302 | opus_int lossCnt; | 303 | opus_int lossCnt; |
303 | opus_int prevSignalType; | 304 | opus_int prevSignalType; |
305 | int arch; | ||
304 | 306 | ||
305 | silk_PLC_struct sPLC; | 307 | silk_PLC_struct sPLC; |
306 | 308 | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/sum_sqr_shift.c b/lib/rbcodec/codecs/libopus/silk/sum_sqr_shift.c index 129df191d8..4fd0c3d7d5 100644 --- a/lib/rbcodec/codecs/libopus/silk/sum_sqr_shift.c +++ b/lib/rbcodec/codecs/libopus/silk/sum_sqr_shift.c | |||
@@ -41,43 +41,40 @@ void silk_sum_sqr_shift( | |||
41 | ) | 41 | ) |
42 | { | 42 | { |
43 | opus_int i, shft; | 43 | opus_int i, shft; |
44 | opus_int32 nrg_tmp, nrg; | 44 | opus_uint32 nrg_tmp; |
45 | opus_int32 nrg; | ||
45 | 46 | ||
46 | nrg = 0; | 47 | /* Do a first run with the maximum shift we could have. */ |
47 | shft = 0; | 48 | shft = 31-silk_CLZ32(len); |
48 | len--; | 49 | /* Let's be conservative with rounding and start with nrg=len. */ |
49 | for( i = 0; i < len; i += 2 ) { | 50 | nrg = len; |
50 | nrg = silk_SMLABB_ovflw( nrg, x[ i ], x[ i ] ); | 51 | for( i = 0; i < len - 1; i += 2 ) { |
51 | nrg = silk_SMLABB_ovflw( nrg, x[ i + 1 ], x[ i + 1 ] ); | 52 | nrg_tmp = silk_SMULBB( x[ i ], x[ i ] ); |
52 | if( nrg < 0 ) { | 53 | nrg_tmp = silk_SMLABB_ovflw( nrg_tmp, x[ i + 1 ], x[ i + 1 ] ); |
53 | /* Scale down */ | 54 | nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, nrg_tmp, shft ); |
54 | nrg = (opus_int32)silk_RSHIFT_uint( (opus_uint32)nrg, 2 ); | ||
55 | shft = 2; | ||
56 | i+=2; | ||
57 | break; | ||
58 | } | ||
59 | } | 55 | } |
60 | for( ; i < len; i += 2 ) { | 56 | if( i < len ) { |
57 | /* One sample left to process */ | ||
58 | nrg_tmp = silk_SMULBB( x[ i ], x[ i ] ); | ||
59 | nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, nrg_tmp, shft ); | ||
60 | } | ||
61 | silk_assert( nrg >= 0 ); | ||
62 | /* Make sure the result will fit in a 32-bit signed integer with two bits | ||
63 | of headroom. */ | ||
64 | shft = silk_max_32(0, shft+3 - silk_CLZ32(nrg)); | ||
65 | nrg = 0; | ||
66 | for( i = 0 ; i < len - 1; i += 2 ) { | ||
61 | nrg_tmp = silk_SMULBB( x[ i ], x[ i ] ); | 67 | nrg_tmp = silk_SMULBB( x[ i ], x[ i ] ); |
62 | nrg_tmp = silk_SMLABB_ovflw( nrg_tmp, x[ i + 1 ], x[ i + 1 ] ); | 68 | nrg_tmp = silk_SMLABB_ovflw( nrg_tmp, x[ i + 1 ], x[ i + 1 ] ); |
63 | nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, (opus_uint32)nrg_tmp, shft ); | 69 | nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, nrg_tmp, shft ); |
64 | if( nrg < 0 ) { | ||
65 | /* Scale down */ | ||
66 | nrg = (opus_int32)silk_RSHIFT_uint( (opus_uint32)nrg, 2 ); | ||
67 | shft += 2; | ||
68 | } | ||
69 | } | 70 | } |
70 | if( i == len ) { | 71 | if( i < len ) { |
71 | /* One sample left to process */ | 72 | /* One sample left to process */ |
72 | nrg_tmp = silk_SMULBB( x[ i ], x[ i ] ); | 73 | nrg_tmp = silk_SMULBB( x[ i ], x[ i ] ); |
73 | nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, nrg_tmp, shft ); | 74 | nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, nrg_tmp, shft ); |
74 | } | 75 | } |
75 | 76 | ||
76 | /* Make sure to have at least one extra leading zero (two leading zeros in total) */ | 77 | silk_assert( nrg >= 0 ); |
77 | if( nrg & 0xC0000000 ) { | ||
78 | nrg = silk_RSHIFT_uint( (opus_uint32)nrg, 2 ); | ||
79 | shft += 2; | ||
80 | } | ||
81 | 78 | ||
82 | /* Output arguments */ | 79 | /* Output arguments */ |
83 | *shift = shft; | 80 | *shift = shft; |
diff --git a/lib/rbcodec/codecs/libopus/silk/tables.h b/lib/rbcodec/codecs/libopus/silk/tables.h index a91431e854..95230c451a 100644 --- a/lib/rbcodec/codecs/libopus/silk/tables.h +++ b/lib/rbcodec/codecs/libopus/silk/tables.h | |||
@@ -47,8 +47,8 @@ extern const opus_uint8 silk_pitch_contour_NB_iCDF[ 11 ]; | |||
47 | extern const opus_uint8 silk_pitch_contour_10_ms_iCDF[ 12 ]; /* 12 */ | 47 | extern const opus_uint8 silk_pitch_contour_10_ms_iCDF[ 12 ]; /* 12 */ |
48 | extern const opus_uint8 silk_pitch_contour_10_ms_NB_iCDF[ 3 ]; /* 3 */ | 48 | extern const opus_uint8 silk_pitch_contour_10_ms_NB_iCDF[ 3 ]; /* 3 */ |
49 | 49 | ||
50 | extern const opus_uint8 silk_pulses_per_block_iCDF[ N_RATE_LEVELS ][ MAX_PULSES + 2 ]; /* 180 */ | 50 | extern const opus_uint8 silk_pulses_per_block_iCDF[ N_RATE_LEVELS ][ SILK_MAX_PULSES + 2 ]; /* 180 */ |
51 | extern const opus_uint8 silk_pulses_per_block_BITS_Q5[ N_RATE_LEVELS - 1 ][ MAX_PULSES + 2 ]; /* 162 */ | 51 | extern const opus_uint8 silk_pulses_per_block_BITS_Q5[ N_RATE_LEVELS - 1 ][ SILK_MAX_PULSES + 2 ]; /* 162 */ |
52 | 52 | ||
53 | extern const opus_uint8 silk_rate_levels_iCDF[ 2 ][ N_RATE_LEVELS - 1 ]; /* 18 */ | 53 | extern const opus_uint8 silk_rate_levels_iCDF[ 2 ][ N_RATE_LEVELS - 1 ]; /* 18 */ |
54 | extern const opus_uint8 silk_rate_levels_BITS_Q5[ 2 ][ N_RATE_LEVELS - 1 ]; /* 18 */ | 54 | extern const opus_uint8 silk_rate_levels_BITS_Q5[ 2 ][ N_RATE_LEVELS - 1 ]; /* 18 */ |
@@ -59,7 +59,7 @@ extern const opus_uint8 silk_shell_code_table0[ 152 ]; | |||
59 | extern const opus_uint8 silk_shell_code_table1[ 152 ]; /* 152 */ | 59 | extern const opus_uint8 silk_shell_code_table1[ 152 ]; /* 152 */ |
60 | extern const opus_uint8 silk_shell_code_table2[ 152 ]; /* 152 */ | 60 | extern const opus_uint8 silk_shell_code_table2[ 152 ]; /* 152 */ |
61 | extern const opus_uint8 silk_shell_code_table3[ 152 ]; /* 152 */ | 61 | extern const opus_uint8 silk_shell_code_table3[ 152 ]; /* 152 */ |
62 | extern const opus_uint8 silk_shell_code_table_offsets[ MAX_PULSES + 1 ]; /* 17 */ | 62 | extern const opus_uint8 silk_shell_code_table_offsets[ SILK_MAX_PULSES + 1 ]; /* 17 */ |
63 | 63 | ||
64 | extern const opus_uint8 silk_lsb_iCDF[ 2 ]; /* 2 */ | 64 | extern const opus_uint8 silk_lsb_iCDF[ 2 ]; /* 2 */ |
65 | 65 | ||
@@ -76,10 +76,8 @@ extern const opus_uint8 silk_NLSF_EXT_iCDF[ 7 ]; | |||
76 | extern const opus_uint8 silk_LTP_per_index_iCDF[ 3 ]; /* 3 */ | 76 | extern const opus_uint8 silk_LTP_per_index_iCDF[ 3 ]; /* 3 */ |
77 | extern const opus_uint8 * const silk_LTP_gain_iCDF_ptrs[ NB_LTP_CBKS ]; /* 3 */ | 77 | extern const opus_uint8 * const silk_LTP_gain_iCDF_ptrs[ NB_LTP_CBKS ]; /* 3 */ |
78 | extern const opus_uint8 * const silk_LTP_gain_BITS_Q5_ptrs[ NB_LTP_CBKS ]; /* 3 */ | 78 | extern const opus_uint8 * const silk_LTP_gain_BITS_Q5_ptrs[ NB_LTP_CBKS ]; /* 3 */ |
79 | extern const opus_int16 silk_LTP_gain_middle_avg_RD_Q14; | ||
80 | extern const opus_int8 * const silk_LTP_vq_ptrs_Q7[ NB_LTP_CBKS ]; /* 168 */ | 79 | extern const opus_int8 * const silk_LTP_vq_ptrs_Q7[ NB_LTP_CBKS ]; /* 168 */ |
81 | extern const opus_uint8 * const silk_LTP_vq_gain_ptrs_Q7[NB_LTP_CBKS]; | 80 | extern const opus_uint8 * const silk_LTP_vq_gain_ptrs_Q7[NB_LTP_CBKS]; |
82 | |||
83 | extern const opus_int8 silk_LTP_vq_sizes[ NB_LTP_CBKS ]; /* 3 */ | 81 | extern const opus_int8 silk_LTP_vq_sizes[ NB_LTP_CBKS ]; /* 3 */ |
84 | 82 | ||
85 | extern const opus_uint8 silk_LTPscale_iCDF[ 3 ]; /* 4 */ | 83 | extern const opus_uint8 silk_LTPscale_iCDF[ 3 ]; /* 4 */ |
@@ -99,12 +97,6 @@ extern const opus_uint8 silk_NLSF_interpolation_factor_iCDF[ 5 ]; | |||
99 | extern const silk_NLSF_CB_struct silk_NLSF_CB_WB; /* 1040 */ | 97 | extern const silk_NLSF_CB_struct silk_NLSF_CB_WB; /* 1040 */ |
100 | extern const silk_NLSF_CB_struct silk_NLSF_CB_NB_MB; /* 728 */ | 98 | extern const silk_NLSF_CB_struct silk_NLSF_CB_NB_MB; /* 728 */ |
101 | 99 | ||
102 | /* Piece-wise linear mapping from bitrate in kbps to coding quality in dB SNR */ | ||
103 | extern const opus_int32 silk_TargetRate_table_NB[ TARGET_RATE_TAB_SZ ]; /* 32 */ | ||
104 | extern const opus_int32 silk_TargetRate_table_MB[ TARGET_RATE_TAB_SZ ]; /* 32 */ | ||
105 | extern const opus_int32 silk_TargetRate_table_WB[ TARGET_RATE_TAB_SZ ]; /* 32 */ | ||
106 | extern const opus_int16 silk_SNR_table_Q1[ TARGET_RATE_TAB_SZ ]; /* 32 */ | ||
107 | |||
108 | /* Quantization offsets */ | 100 | /* Quantization offsets */ |
109 | extern const opus_int16 silk_Quantization_Offsets_Q10[ 2 ][ 2 ]; /* 8 */ | 101 | extern const opus_int16 silk_Quantization_Offsets_Q10[ 2 ][ 2 ]; /* 8 */ |
110 | 102 | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/tables_LTP.c b/lib/rbcodec/codecs/libopus/silk/tables_LTP.c index ea518652b8..5e12c8643e 100644 --- a/lib/rbcodec/codecs/libopus/silk/tables_LTP.c +++ b/lib/rbcodec/codecs/libopus/silk/tables_LTP.c | |||
@@ -51,9 +51,6 @@ static const opus_uint8 silk_LTP_gain_iCDF_2[32] = { | |||
51 | 24, 20, 16, 12, 9, 5, 2, 0 | 51 | 24, 20, 16, 12, 9, 5, 2, 0 |
52 | }; | 52 | }; |
53 | 53 | ||
54 | #if 0 | ||
55 | const opus_int16 silk_LTP_gain_middle_avg_RD_Q14 = 12304; | ||
56 | |||
57 | static const opus_uint8 silk_LTP_gain_BITS_Q5_0[8] = { | 54 | static const opus_uint8 silk_LTP_gain_BITS_Q5_0[8] = { |
58 | 15, 131, 138, 138, 155, 155, 173, 173 | 55 | 15, 131, 138, 138, 155, 155, 173, 173 |
59 | }; | 56 | }; |
@@ -69,7 +66,6 @@ static const opus_uint8 silk_LTP_gain_BITS_Q5_2[32] = { | |||
69 | 160, 160, 166, 166, 173, 173, 182, 192, | 66 | 160, 160, 166, 166, 173, 173, 182, 192, |
70 | 182, 192, 192, 192, 205, 192, 205, 224 | 67 | 182, 192, 192, 192, 205, 192, 205, 224 |
71 | }; | 68 | }; |
72 | #endif | ||
73 | 69 | ||
74 | const opus_uint8 * const silk_LTP_gain_iCDF_ptrs[NB_LTP_CBKS] = { | 70 | const opus_uint8 * const silk_LTP_gain_iCDF_ptrs[NB_LTP_CBKS] = { |
75 | silk_LTP_gain_iCDF_0, | 71 | silk_LTP_gain_iCDF_0, |
@@ -77,13 +73,11 @@ const opus_uint8 * const silk_LTP_gain_iCDF_ptrs[NB_LTP_CBKS] = { | |||
77 | silk_LTP_gain_iCDF_2 | 73 | silk_LTP_gain_iCDF_2 |
78 | }; | 74 | }; |
79 | 75 | ||
80 | #if 0 | ||
81 | const opus_uint8 * const silk_LTP_gain_BITS_Q5_ptrs[NB_LTP_CBKS] = { | 76 | const opus_uint8 * const silk_LTP_gain_BITS_Q5_ptrs[NB_LTP_CBKS] = { |
82 | silk_LTP_gain_BITS_Q5_0, | 77 | silk_LTP_gain_BITS_Q5_0, |
83 | silk_LTP_gain_BITS_Q5_1, | 78 | silk_LTP_gain_BITS_Q5_1, |
84 | silk_LTP_gain_BITS_Q5_2 | 79 | silk_LTP_gain_BITS_Q5_2 |
85 | }; | 80 | }; |
86 | #endif | ||
87 | 81 | ||
88 | static const opus_int8 silk_LTP_gain_vq_0[8][5] = | 82 | static const opus_int8 silk_LTP_gain_vq_0[8][5] = |
89 | { | 83 | { |
@@ -271,7 +265,6 @@ const opus_int8 * const silk_LTP_vq_ptrs_Q7[NB_LTP_CBKS] = { | |||
271 | (opus_int8 *)&silk_LTP_gain_vq_2[0][0] | 265 | (opus_int8 *)&silk_LTP_gain_vq_2[0][0] |
272 | }; | 266 | }; |
273 | 267 | ||
274 | #if 0 | ||
275 | /* Maximum frequency-dependent response of the pitch taps above, | 268 | /* Maximum frequency-dependent response of the pitch taps above, |
276 | computed as max(abs(freqz(taps))) */ | 269 | computed as max(abs(freqz(taps))) */ |
277 | static const opus_uint8 silk_LTP_gain_vq_0_gain[8] = { | 270 | static const opus_uint8 silk_LTP_gain_vq_0_gain[8] = { |
@@ -299,4 +292,3 @@ const opus_uint8 * const silk_LTP_vq_gain_ptrs_Q7[NB_LTP_CBKS] = { | |||
299 | const opus_int8 silk_LTP_vq_sizes[NB_LTP_CBKS] = { | 292 | const opus_int8 silk_LTP_vq_sizes[NB_LTP_CBKS] = { |
300 | 8, 16, 32 | 293 | 8, 16, 32 |
301 | }; | 294 | }; |
302 | #endif | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/tables_NLSF_CB_NB_MB.c b/lib/rbcodec/codecs/libopus/silk/tables_NLSF_CB_NB_MB.c index 8c59d207aa..195d5b95bd 100644 --- a/lib/rbcodec/codecs/libopus/silk/tables_NLSF_CB_NB_MB.c +++ b/lib/rbcodec/codecs/libopus/silk/tables_NLSF_CB_NB_MB.c | |||
@@ -74,6 +74,41 @@ static const opus_uint8 silk_NLSF_CB1_NB_MB_Q8[ 320 ] = { | |||
74 | 64, 84, 104, 118, 156, 177, 201, 230 | 74 | 64, 84, 104, 118, 156, 177, 201, 230 |
75 | }; | 75 | }; |
76 | 76 | ||
77 | static const opus_int16 silk_NLSF_CB1_Wght_Q9[ 320 ] = { | ||
78 | 2897, 2314, 2314, 2314, 2287, 2287, 2314, 2300, 2327, 2287, | ||
79 | 2888, 2580, 2394, 2367, 2314, 2274, 2274, 2274, 2274, 2194, | ||
80 | 2487, 2340, 2340, 2314, 2314, 2314, 2340, 2340, 2367, 2354, | ||
81 | 3216, 2766, 2340, 2340, 2314, 2274, 2221, 2207, 2261, 2194, | ||
82 | 2460, 2474, 2367, 2394, 2394, 2394, 2394, 2367, 2407, 2314, | ||
83 | 3479, 3056, 2127, 2207, 2274, 2274, 2274, 2287, 2314, 2261, | ||
84 | 3282, 3141, 2580, 2394, 2247, 2221, 2207, 2194, 2194, 2114, | ||
85 | 4096, 3845, 2221, 2620, 2620, 2407, 2314, 2394, 2367, 2074, | ||
86 | 3178, 3244, 2367, 2221, 2553, 2434, 2340, 2314, 2167, 2221, | ||
87 | 3338, 3488, 2726, 2194, 2261, 2460, 2354, 2367, 2207, 2101, | ||
88 | 2354, 2420, 2327, 2367, 2394, 2420, 2420, 2420, 2460, 2367, | ||
89 | 3779, 3629, 2434, 2527, 2367, 2274, 2274, 2300, 2207, 2048, | ||
90 | 3254, 3225, 2713, 2846, 2447, 2327, 2300, 2300, 2274, 2127, | ||
91 | 3263, 3300, 2753, 2806, 2447, 2261, 2261, 2247, 2127, 2101, | ||
92 | 2873, 2981, 2633, 2367, 2407, 2354, 2194, 2247, 2247, 2114, | ||
93 | 3225, 3197, 2633, 2580, 2274, 2181, 2247, 2221, 2221, 2141, | ||
94 | 3178, 3310, 2740, 2407, 2274, 2274, 2274, 2287, 2194, 2114, | ||
95 | 3141, 3272, 2460, 2061, 2287, 2500, 2367, 2487, 2434, 2181, | ||
96 | 3507, 3282, 2314, 2700, 2647, 2474, 2367, 2394, 2340, 2127, | ||
97 | 3423, 3535, 3038, 3056, 2300, 1950, 2221, 2274, 2274, 2274, | ||
98 | 3404, 3366, 2087, 2687, 2873, 2354, 2420, 2274, 2474, 2540, | ||
99 | 3760, 3488, 1950, 2660, 2897, 2527, 2394, 2367, 2460, 2261, | ||
100 | 3028, 3272, 2740, 2888, 2740, 2154, 2127, 2287, 2234, 2247, | ||
101 | 3695, 3657, 2025, 1969, 2660, 2700, 2580, 2500, 2327, 2367, | ||
102 | 3207, 3413, 2354, 2074, 2888, 2888, 2340, 2487, 2247, 2167, | ||
103 | 3338, 3366, 2846, 2780, 2327, 2154, 2274, 2287, 2114, 2061, | ||
104 | 2327, 2300, 2181, 2167, 2181, 2367, 2633, 2700, 2700, 2553, | ||
105 | 2407, 2434, 2221, 2261, 2221, 2221, 2340, 2420, 2607, 2700, | ||
106 | 3038, 3244, 2806, 2888, 2474, 2074, 2300, 2314, 2354, 2380, | ||
107 | 2221, 2154, 2127, 2287, 2500, 2793, 2793, 2620, 2580, 2367, | ||
108 | 3676, 3713, 2234, 1838, 2181, 2753, 2726, 2673, 2513, 2207, | ||
109 | 2793, 3160, 2726, 2553, 2846, 2513, 2181, 2394, 2221, 2181 | ||
110 | }; | ||
111 | |||
77 | static const opus_uint8 silk_NLSF_CB1_iCDF_NB_MB[ 64 ] = { | 112 | static const opus_uint8 silk_NLSF_CB1_iCDF_NB_MB[ 64 ] = { |
78 | 212, 178, 148, 129, 108, 96, 85, 82, | 113 | 212, 178, 148, 129, 108, 96, 85, 82, |
79 | 79, 77, 61, 59, 57, 56, 51, 49, | 114 | 79, 77, 61, 59, 57, 56, 51, 49, |
@@ -150,6 +185,7 @@ const silk_NLSF_CB_struct silk_NLSF_CB_NB_MB = | |||
150 | SILK_FIX_CONST( 0.18, 16 ), | 185 | SILK_FIX_CONST( 0.18, 16 ), |
151 | SILK_FIX_CONST( 1.0 / 0.18, 6 ), | 186 | SILK_FIX_CONST( 1.0 / 0.18, 6 ), |
152 | silk_NLSF_CB1_NB_MB_Q8, | 187 | silk_NLSF_CB1_NB_MB_Q8, |
188 | silk_NLSF_CB1_Wght_Q9, | ||
153 | silk_NLSF_CB1_iCDF_NB_MB, | 189 | silk_NLSF_CB1_iCDF_NB_MB, |
154 | silk_NLSF_PRED_NB_MB_Q8, | 190 | silk_NLSF_PRED_NB_MB_Q8, |
155 | silk_NLSF_CB2_SELECT_NB_MB, | 191 | silk_NLSF_CB2_SELECT_NB_MB, |
diff --git a/lib/rbcodec/codecs/libopus/silk/tables_NLSF_CB_WB.c b/lib/rbcodec/codecs/libopus/silk/tables_NLSF_CB_WB.c index 50af87eb2e..5cc9f57bff 100644 --- a/lib/rbcodec/codecs/libopus/silk/tables_NLSF_CB_WB.c +++ b/lib/rbcodec/codecs/libopus/silk/tables_NLSF_CB_WB.c | |||
@@ -98,6 +98,41 @@ static const opus_uint8 silk_NLSF_CB1_WB_Q8[ 512 ] = { | |||
98 | 110, 119, 129, 141, 175, 198, 218, 237 | 98 | 110, 119, 129, 141, 175, 198, 218, 237 |
99 | }; | 99 | }; |
100 | 100 | ||
101 | static const opus_int16 silk_NLSF_CB1_WB_Wght_Q9[ 512 ] = { | ||
102 | 3657, 2925, 2925, 2925, 2925, 2925, 2925, 2925, 2925, 2925, 2925, 2925, 2963, 2963, 2925, 2846, | ||
103 | 3216, 3085, 2972, 3056, 3056, 3010, 3010, 3010, 2963, 2963, 3010, 2972, 2888, 2846, 2846, 2726, | ||
104 | 3920, 4014, 2981, 3207, 3207, 2934, 3056, 2846, 3122, 3244, 2925, 2846, 2620, 2553, 2780, 2925, | ||
105 | 3516, 3197, 3010, 3103, 3019, 2888, 2925, 2925, 2925, 2925, 2888, 2888, 2888, 2888, 2888, 2753, | ||
106 | 5054, 5054, 2934, 3573, 3385, 3056, 3085, 2793, 3160, 3160, 2972, 2846, 2513, 2540, 2753, 2888, | ||
107 | 4428, 4149, 2700, 2753, 2972, 3010, 2925, 2846, 2981, 3019, 2925, 2925, 2925, 2925, 2888, 2726, | ||
108 | 3620, 3019, 2972, 3056, 3056, 2873, 2806, 3056, 3216, 3047, 2981, 3291, 3291, 2981, 3310, 2991, | ||
109 | 5227, 5014, 2540, 3338, 3526, 3385, 3197, 3094, 3376, 2981, 2700, 2647, 2687, 2793, 2846, 2673, | ||
110 | 5081, 5174, 4615, 4428, 2460, 2897, 3047, 3207, 3169, 2687, 2740, 2888, 2846, 2793, 2846, 2700, | ||
111 | 3122, 2888, 2963, 2925, 2925, 2925, 2925, 2963, 2963, 2963, 2963, 2925, 2925, 2963, 2963, 2963, | ||
112 | 4202, 3207, 2981, 3103, 3010, 2888, 2888, 2925, 2972, 2873, 2916, 3019, 2972, 3010, 3197, 2873, | ||
113 | 3760, 3760, 3244, 3103, 2981, 2888, 2925, 2888, 2972, 2934, 2793, 2793, 2846, 2888, 2888, 2660, | ||
114 | 3854, 4014, 3207, 3122, 3244, 2934, 3047, 2963, 2963, 3085, 2846, 2793, 2793, 2793, 2793, 2580, | ||
115 | 3845, 4080, 3357, 3516, 3094, 2740, 3010, 2934, 3122, 3085, 2846, 2846, 2647, 2647, 2846, 2806, | ||
116 | 5147, 4894, 3225, 3845, 3441, 3169, 2897, 3413, 3451, 2700, 2580, 2673, 2740, 2846, 2806, 2753, | ||
117 | 4109, 3789, 3291, 3160, 2925, 2888, 2888, 2925, 2793, 2740, 2793, 2740, 2793, 2846, 2888, 2806, | ||
118 | 5081, 5054, 3047, 3545, 3244, 3056, 3085, 2944, 3103, 2897, 2740, 2740, 2740, 2846, 2793, 2620, | ||
119 | 4309, 4309, 2860, 2527, 3207, 3376, 3376, 3075, 3075, 3376, 3056, 2846, 2647, 2580, 2726, 2753, | ||
120 | 3056, 2916, 2806, 2888, 2740, 2687, 2897, 3103, 3150, 3150, 3216, 3169, 3056, 3010, 2963, 2846, | ||
121 | 4375, 3882, 2925, 2888, 2846, 2888, 2846, 2846, 2888, 2888, 2888, 2846, 2888, 2925, 2888, 2846, | ||
122 | 2981, 2916, 2916, 2981, 2981, 3056, 3122, 3216, 3150, 3056, 3010, 2972, 2972, 2972, 2925, 2740, | ||
123 | 4229, 4149, 3310, 3347, 2925, 2963, 2888, 2981, 2981, 2846, 2793, 2740, 2846, 2846, 2846, 2793, | ||
124 | 4080, 4014, 3103, 3010, 2925, 2925, 2925, 2888, 2925, 2925, 2846, 2846, 2846, 2793, 2888, 2780, | ||
125 | 4615, 4575, 3169, 3441, 3207, 2981, 2897, 3038, 3122, 2740, 2687, 2687, 2687, 2740, 2793, 2700, | ||
126 | 4149, 4269, 3789, 3657, 2726, 2780, 2888, 2888, 3010, 2972, 2925, 2846, 2687, 2687, 2793, 2888, | ||
127 | 4215, 3554, 2753, 2846, 2846, 2888, 2888, 2888, 2925, 2925, 2888, 2925, 2925, 2925, 2963, 2888, | ||
128 | 5174, 4921, 2261, 3432, 3789, 3479, 3347, 2846, 3310, 3479, 3150, 2897, 2460, 2487, 2753, 2925, | ||
129 | 3451, 3685, 3122, 3197, 3357, 3047, 3207, 3207, 2981, 3216, 3085, 2925, 2925, 2687, 2540, 2434, | ||
130 | 2981, 3010, 2793, 2793, 2740, 2793, 2846, 2972, 3056, 3103, 3150, 3150, 3150, 3103, 3010, 3010, | ||
131 | 2944, 2873, 2687, 2726, 2780, 3010, 3432, 3545, 3357, 3244, 3056, 3010, 2963, 2925, 2888, 2846, | ||
132 | 3019, 2944, 2897, 3010, 3010, 2972, 3019, 3103, 3056, 3056, 3010, 2888, 2846, 2925, 2925, 2888, | ||
133 | 3920, 3967, 3010, 3197, 3357, 3216, 3291, 3291, 3479, 3704, 3441, 2726, 2181, 2460, 2580, 2607 | ||
134 | }; | ||
135 | |||
101 | static const opus_uint8 silk_NLSF_CB1_iCDF_WB[ 64 ] = { | 136 | static const opus_uint8 silk_NLSF_CB1_iCDF_WB[ 64 ] = { |
102 | 225, 204, 201, 184, 183, 175, 158, 154, | 137 | 225, 204, 201, 184, 183, 175, 158, 154, |
103 | 153, 135, 119, 115, 113, 110, 109, 99, | 138 | 153, 135, 119, 115, 113, 110, 109, 99, |
@@ -188,6 +223,7 @@ const silk_NLSF_CB_struct silk_NLSF_CB_WB = | |||
188 | SILK_FIX_CONST( 0.15, 16 ), | 223 | SILK_FIX_CONST( 0.15, 16 ), |
189 | SILK_FIX_CONST( 1.0 / 0.15, 6 ), | 224 | SILK_FIX_CONST( 1.0 / 0.15, 6 ), |
190 | silk_NLSF_CB1_WB_Q8, | 225 | silk_NLSF_CB1_WB_Q8, |
226 | silk_NLSF_CB1_WB_Wght_Q9, | ||
191 | silk_NLSF_CB1_iCDF_WB, | 227 | silk_NLSF_CB1_iCDF_WB, |
192 | silk_NLSF_PRED_WB_Q8, | 228 | silk_NLSF_PRED_WB_Q8, |
193 | silk_NLSF_CB2_SELECT_WB, | 229 | silk_NLSF_CB2_SELECT_WB, |
diff --git a/lib/rbcodec/codecs/libopus/silk/tables_other.c b/lib/rbcodec/codecs/libopus/silk/tables_other.c index 398686bf26..e34d90777b 100644 --- a/lib/rbcodec/codecs/libopus/silk/tables_other.c +++ b/lib/rbcodec/codecs/libopus/silk/tables_other.c | |||
@@ -38,20 +38,6 @@ extern "C" | |||
38 | { | 38 | { |
39 | #endif | 39 | #endif |
40 | 40 | ||
41 | /* Piece-wise linear mapping from bitrate in kbps to coding quality in dB SNR */ | ||
42 | const opus_int32 silk_TargetRate_table_NB[ TARGET_RATE_TAB_SZ ] = { | ||
43 | 0, 8000, 9400, 11500, 13500, 17500, 25000, MAX_TARGET_RATE_BPS | ||
44 | }; | ||
45 | const opus_int32 silk_TargetRate_table_MB[ TARGET_RATE_TAB_SZ ] = { | ||
46 | 0, 9000, 12000, 14500, 18500, 24500, 35500, MAX_TARGET_RATE_BPS | ||
47 | }; | ||
48 | const opus_int32 silk_TargetRate_table_WB[ TARGET_RATE_TAB_SZ ] = { | ||
49 | 0, 10500, 14000, 17000, 21500, 28500, 42000, MAX_TARGET_RATE_BPS | ||
50 | }; | ||
51 | const opus_int16 silk_SNR_table_Q1[ TARGET_RATE_TAB_SZ ] = { | ||
52 | 18, 29, 38, 40, 46, 52, 62, 84 | ||
53 | }; | ||
54 | |||
55 | /* Tables for stereo predictor coding */ | 41 | /* Tables for stereo predictor coding */ |
56 | const opus_int16 silk_stereo_pred_quant_Q13[ STEREO_QUANT_TAB_SIZE ] = { | 42 | const opus_int16 silk_stereo_pred_quant_Q13[ STEREO_QUANT_TAB_SIZE ] = { |
57 | -13732, -10050, -8266, -7526, -6500, -5000, -2950, -820, | 43 | -13732, -10050, -8266, -7526, -6500, -5000, -2950, -820, |
diff --git a/lib/rbcodec/codecs/libopus/silk/tests/test_unit_LPC_inv_pred_gain.c b/lib/rbcodec/codecs/libopus/silk/tests/test_unit_LPC_inv_pred_gain.c new file mode 100644 index 0000000000..67067cead7 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/tests/test_unit_LPC_inv_pred_gain.c | |||
@@ -0,0 +1,129 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2017 Google Inc., Jean-Marc Valin | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include <stdio.h> | ||
33 | #include <stdlib.h> | ||
34 | #include "celt/stack_alloc.h" | ||
35 | #include "cpu_support.h" | ||
36 | #include "SigProc_FIX.h" | ||
37 | |||
38 | /* Computes the impulse response of the filter so we | ||
39 | can catch filters that are definitely unstable. Some | ||
40 | unstable filters may be classified as stable, but not | ||
41 | the other way around. */ | ||
42 | int check_stability(opus_int16 *A_Q12, int order) { | ||
43 | int i; | ||
44 | int j; | ||
45 | int sum_a, sum_abs_a; | ||
46 | sum_a = sum_abs_a = 0; | ||
47 | for( j = 0; j < order; j++ ) { | ||
48 | sum_a += A_Q12[ j ]; | ||
49 | sum_abs_a += silk_abs( A_Q12[ j ] ); | ||
50 | } | ||
51 | /* Check DC stability. */ | ||
52 | if( sum_a >= 4096 ) { | ||
53 | return 0; | ||
54 | } | ||
55 | /* If the sum of absolute values is less than 1, the filter | ||
56 | has to be stable. */ | ||
57 | if( sum_abs_a < 4096 ) { | ||
58 | return 1; | ||
59 | } | ||
60 | double y[SILK_MAX_ORDER_LPC] = {0}; | ||
61 | y[0] = 1; | ||
62 | for( i = 0; i < 10000; i++ ) { | ||
63 | double sum = 0; | ||
64 | for( j = 0; j < order; j++ ) { | ||
65 | sum += y[ j ]*A_Q12[ j ]; | ||
66 | } | ||
67 | for( j = order - 1; j > 0; j-- ) { | ||
68 | y[ j ] = y[ j - 1 ]; | ||
69 | } | ||
70 | y[ 0 ] = sum*(1./4096); | ||
71 | /* If impulse response reaches +/- 10000, the filter | ||
72 | is definitely unstable. */ | ||
73 | if( !(y[ 0 ] < 10000 && y[ 0 ] > -10000) ) { | ||
74 | return 0; | ||
75 | } | ||
76 | /* Test every 8 sample for low amplitude. */ | ||
77 | if( ( i & 0x7 ) == 0 ) { | ||
78 | double amp = 0; | ||
79 | for( j = 0; j < order; j++ ) { | ||
80 | amp += fabs(y[j]); | ||
81 | } | ||
82 | if( amp < 0.00001 ) { | ||
83 | return 1; | ||
84 | } | ||
85 | } | ||
86 | } | ||
87 | return 1; | ||
88 | } | ||
89 | |||
90 | int main(void) { | ||
91 | const int arch = opus_select_arch(); | ||
92 | /* Set to 10000 so all branches in C function are triggered */ | ||
93 | const int loop_num = 10000; | ||
94 | int count = 0; | ||
95 | ALLOC_STACK; | ||
96 | |||
97 | /* FIXME: Make the seed random (with option to set it explicitly) | ||
98 | so we get wider coverage. */ | ||
99 | srand(0); | ||
100 | |||
101 | printf("Testing silk_LPC_inverse_pred_gain() optimization ...\n"); | ||
102 | for( count = 0; count < loop_num; count++ ) { | ||
103 | unsigned int i; | ||
104 | opus_int order; | ||
105 | unsigned int shift; | ||
106 | opus_int16 A_Q12[ SILK_MAX_ORDER_LPC ]; | ||
107 | opus_int32 gain; | ||
108 | |||
109 | for( order = 2; order <= SILK_MAX_ORDER_LPC; order += 2 ) { /* order must be even. */ | ||
110 | for( shift = 0; shift < 16; shift++ ) { /* Different dynamic range. */ | ||
111 | for( i = 0; i < SILK_MAX_ORDER_LPC; i++ ) { | ||
112 | A_Q12[i] = ((opus_int16)rand()) >> shift; | ||
113 | } | ||
114 | gain = silk_LPC_inverse_pred_gain(A_Q12, order, arch); | ||
115 | /* Look for filters that silk_LPC_inverse_pred_gain() thinks are | ||
116 | stable but definitely aren't. */ | ||
117 | if( gain != 0 && !check_stability(A_Q12, order) ) { | ||
118 | fprintf(stderr, "**Loop %4d failed!**\n", count); | ||
119 | return 1; | ||
120 | } | ||
121 | } | ||
122 | } | ||
123 | if( !(count % 500) ) { | ||
124 | printf("Loop %4d passed\n", count); | ||
125 | } | ||
126 | } | ||
127 | printf("silk_LPC_inverse_pred_gain() optimization passed\n"); | ||
128 | return 0; | ||
129 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/tuning_parameters.h b/lib/rbcodec/codecs/libopus/silk/tuning_parameters.h new file mode 100644 index 0000000000..d70275fd8f --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/tuning_parameters.h | |||
@@ -0,0 +1,155 @@ | |||
1 | /*********************************************************************** | ||
2 | Copyright (c) 2006-2011, Skype Limited. All rights reserved. | ||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | - Redistributions of source code must retain the above copyright notice, | ||
7 | this list of conditions and the following disclaimer. | ||
8 | - Redistributions in binary form must reproduce the above copyright | ||
9 | notice, this list of conditions and the following disclaimer in the | ||
10 | documentation and/or other materials provided with the distribution. | ||
11 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
12 | names of specific contributors, may be used to endorse or promote | ||
13 | products derived from this software without specific prior written | ||
14 | permission. | ||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
25 | POSSIBILITY OF SUCH DAMAGE. | ||
26 | ***********************************************************************/ | ||
27 | |||
28 | #ifndef SILK_TUNING_PARAMETERS_H | ||
29 | #define SILK_TUNING_PARAMETERS_H | ||
30 | |||
31 | #ifdef __cplusplus | ||
32 | extern "C" | ||
33 | { | ||
34 | #endif | ||
35 | |||
36 | /* Decay time for bitreservoir */ | ||
37 | #define BITRESERVOIR_DECAY_TIME_MS 500 | ||
38 | |||
39 | /*******************/ | ||
40 | /* Pitch estimator */ | ||
41 | /*******************/ | ||
42 | |||
43 | /* Level of noise floor for whitening filter LPC analysis in pitch analysis */ | ||
44 | #define FIND_PITCH_WHITE_NOISE_FRACTION 1e-3f | ||
45 | |||
46 | /* Bandwidth expansion for whitening filter in pitch analysis */ | ||
47 | #define FIND_PITCH_BANDWIDTH_EXPANSION 0.99f | ||
48 | |||
49 | /*********************/ | ||
50 | /* Linear prediction */ | ||
51 | /*********************/ | ||
52 | |||
53 | /* LPC analysis regularization */ | ||
54 | #define FIND_LPC_COND_FAC 1e-5f | ||
55 | |||
56 | /* Max cumulative LTP gain */ | ||
57 | #define MAX_SUM_LOG_GAIN_DB 250.0f | ||
58 | |||
59 | /* LTP analysis defines */ | ||
60 | #define LTP_CORR_INV_MAX 0.03f | ||
61 | |||
62 | /***********************/ | ||
63 | /* High pass filtering */ | ||
64 | /***********************/ | ||
65 | |||
66 | /* Smoothing parameters for low end of pitch frequency range estimation */ | ||
67 | #define VARIABLE_HP_SMTH_COEF1 0.1f | ||
68 | #define VARIABLE_HP_SMTH_COEF2 0.015f | ||
69 | #define VARIABLE_HP_MAX_DELTA_FREQ 0.4f | ||
70 | |||
71 | /* Min and max cut-off frequency values (-3 dB points) */ | ||
72 | #define VARIABLE_HP_MIN_CUTOFF_HZ 60 | ||
73 | #define VARIABLE_HP_MAX_CUTOFF_HZ 100 | ||
74 | |||
75 | /***********/ | ||
76 | /* Various */ | ||
77 | /***********/ | ||
78 | |||
79 | /* VAD threshold */ | ||
80 | #define SPEECH_ACTIVITY_DTX_THRES 0.05f | ||
81 | |||
82 | /* Speech Activity LBRR enable threshold */ | ||
83 | #define LBRR_SPEECH_ACTIVITY_THRES 0.3f | ||
84 | |||
85 | /*************************/ | ||
86 | /* Perceptual parameters */ | ||
87 | /*************************/ | ||
88 | |||
89 | /* reduction in coding SNR during low speech activity */ | ||
90 | #define BG_SNR_DECR_dB 2.0f | ||
91 | |||
92 | /* factor for reducing quantization noise during voiced speech */ | ||
93 | #define HARM_SNR_INCR_dB 2.0f | ||
94 | |||
95 | /* factor for reducing quantization noise for unvoiced sparse signals */ | ||
96 | #define SPARSE_SNR_INCR_dB 2.0f | ||
97 | |||
98 | /* threshold for sparseness measure above which to use lower quantization offset during unvoiced */ | ||
99 | #define ENERGY_VARIATION_THRESHOLD_QNT_OFFSET 0.6f | ||
100 | |||
101 | /* warping control */ | ||
102 | #define WARPING_MULTIPLIER 0.015f | ||
103 | |||
104 | /* fraction added to first autocorrelation value */ | ||
105 | #define SHAPE_WHITE_NOISE_FRACTION 3e-5f | ||
106 | |||
107 | /* noise shaping filter chirp factor */ | ||
108 | #define BANDWIDTH_EXPANSION 0.94f | ||
109 | |||
110 | /* harmonic noise shaping */ | ||
111 | #define HARMONIC_SHAPING 0.3f | ||
112 | |||
113 | /* extra harmonic noise shaping for high bitrates or noisy input */ | ||
114 | #define HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING 0.2f | ||
115 | |||
116 | /* parameter for shaping noise towards higher frequencies */ | ||
117 | #define HP_NOISE_COEF 0.25f | ||
118 | |||
119 | /* parameter for shaping noise even more towards higher frequencies during voiced speech */ | ||
120 | #define HARM_HP_NOISE_COEF 0.35f | ||
121 | |||
122 | /* parameter for applying a high-pass tilt to the input signal */ | ||
123 | #define INPUT_TILT 0.05f | ||
124 | |||
125 | /* parameter for extra high-pass tilt to the input signal at high rates */ | ||
126 | #define HIGH_RATE_INPUT_TILT 0.1f | ||
127 | |||
128 | /* parameter for reducing noise at the very low frequencies */ | ||
129 | #define LOW_FREQ_SHAPING 4.0f | ||
130 | |||
131 | /* less reduction of noise at the very low frequencies for signals with low SNR at low frequencies */ | ||
132 | #define LOW_QUALITY_LOW_FREQ_SHAPING_DECR 0.5f | ||
133 | |||
134 | /* subframe smoothing coefficient for HarmBoost, HarmShapeGain, Tilt (lower -> more smoothing) */ | ||
135 | #define SUBFR_SMTH_COEF 0.4f | ||
136 | |||
137 | /* parameters defining the R/D tradeoff in the residual quantizer */ | ||
138 | #define LAMBDA_OFFSET 1.2f | ||
139 | #define LAMBDA_SPEECH_ACT -0.2f | ||
140 | #define LAMBDA_DELAYED_DECISIONS -0.05f | ||
141 | #define LAMBDA_INPUT_QUALITY -0.1f | ||
142 | #define LAMBDA_CODING_QUALITY -0.2f | ||
143 | #define LAMBDA_QUANT_OFFSET 0.8f | ||
144 | |||
145 | /* Compensation in bitrate calculations for 10 ms modes */ | ||
146 | #define REDUCE_BITRATE_10_MS_BPS 2200 | ||
147 | |||
148 | /* Maximum time before allowing a bandwidth transition */ | ||
149 | #define MAX_BANDWIDTH_SWITCH_DELAY_MS 5000 | ||
150 | |||
151 | #ifdef __cplusplus | ||
152 | } | ||
153 | #endif | ||
154 | |||
155 | #endif /* SILK_TUNING_PARAMETERS_H */ | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/x86/NSQ_del_dec_sse4_1.c b/lib/rbcodec/codecs/libopus/silk/x86/NSQ_del_dec_sse4_1.c new file mode 100644 index 0000000000..2c75ede2dd --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/x86/NSQ_del_dec_sse4_1.c | |||
@@ -0,0 +1,859 @@ | |||
1 | /* Copyright (c) 2014, Cisco Systems, INC | ||
2 | Written by XiangMingZhu WeiZhou MinPeng YanWang | ||
3 | |||
4 | Redistribution and use in source and binary forms, with or without | ||
5 | modification, are permitted provided that the following conditions | ||
6 | are met: | ||
7 | |||
8 | - Redistributions of source code must retain the above copyright | ||
9 | notice, this list of conditions and the following disclaimer. | ||
10 | |||
11 | - Redistributions in binary form must reproduce the above copyright | ||
12 | notice, this list of conditions and the following disclaimer in the | ||
13 | documentation and/or other materials provided with the distribution. | ||
14 | |||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
16 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
17 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
18 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER | ||
19 | OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
20 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
21 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
22 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
23 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
24 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include <xmmintrin.h> | ||
33 | #include <emmintrin.h> | ||
34 | #include <smmintrin.h> | ||
35 | #include "main.h" | ||
36 | #include "celt/x86/x86cpu.h" | ||
37 | |||
38 | #include "stack_alloc.h" | ||
39 | |||
40 | typedef struct { | ||
41 | opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH ]; | ||
42 | opus_int32 RandState[ DECISION_DELAY ]; | ||
43 | opus_int32 Q_Q10[ DECISION_DELAY ]; | ||
44 | opus_int32 Xq_Q14[ DECISION_DELAY ]; | ||
45 | opus_int32 Pred_Q15[ DECISION_DELAY ]; | ||
46 | opus_int32 Shape_Q14[ DECISION_DELAY ]; | ||
47 | opus_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ]; | ||
48 | opus_int32 LF_AR_Q14; | ||
49 | opus_int32 Seed; | ||
50 | opus_int32 SeedInit; | ||
51 | opus_int32 RD_Q10; | ||
52 | } NSQ_del_dec_struct; | ||
53 | |||
54 | typedef struct { | ||
55 | opus_int32 Q_Q10; | ||
56 | opus_int32 RD_Q10; | ||
57 | opus_int32 xq_Q14; | ||
58 | opus_int32 LF_AR_Q14; | ||
59 | opus_int32 sLTP_shp_Q14; | ||
60 | opus_int32 LPC_exc_Q14; | ||
61 | } NSQ_sample_struct; | ||
62 | |||
63 | typedef NSQ_sample_struct NSQ_sample_pair[ 2 ]; | ||
64 | |||
65 | static OPUS_INLINE void silk_nsq_del_dec_scale_states_sse4_1( | ||
66 | const silk_encoder_state *psEncC, /* I Encoder State */ | ||
67 | silk_nsq_state *NSQ, /* I/O NSQ state */ | ||
68 | NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ | ||
69 | const opus_int32 x_Q3[], /* I Input in Q3 */ | ||
70 | opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */ | ||
71 | const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */ | ||
72 | opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ | ||
73 | opus_int subfr, /* I Subframe number */ | ||
74 | opus_int nStatesDelayedDecision, /* I Number of del dec states */ | ||
75 | const opus_int LTP_scale_Q14, /* I LTP state scaling */ | ||
76 | const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ | ||
77 | const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */ | ||
78 | const opus_int signal_type, /* I Signal type */ | ||
79 | const opus_int decisionDelay /* I Decision delay */ | ||
80 | ); | ||
81 | |||
82 | /******************************************/ | ||
83 | /* Noise shape quantizer for one subframe */ | ||
84 | /******************************************/ | ||
85 | static OPUS_INLINE void silk_noise_shape_quantizer_del_dec_sse4_1( | ||
86 | silk_nsq_state *NSQ, /* I/O NSQ state */ | ||
87 | NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ | ||
88 | opus_int signalType, /* I Signal type */ | ||
89 | const opus_int32 x_Q10[], /* I */ | ||
90 | opus_int8 pulses[], /* O */ | ||
91 | opus_int16 xq[], /* O */ | ||
92 | opus_int32 sLTP_Q15[], /* I/O LTP filter state */ | ||
93 | opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */ | ||
94 | const opus_int16 a_Q12[], /* I Short term prediction coefs */ | ||
95 | const opus_int16 b_Q14[], /* I Long term prediction coefs */ | ||
96 | const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */ | ||
97 | opus_int lag, /* I Pitch lag */ | ||
98 | opus_int32 HarmShapeFIRPacked_Q14, /* I */ | ||
99 | opus_int Tilt_Q14, /* I Spectral tilt */ | ||
100 | opus_int32 LF_shp_Q14, /* I */ | ||
101 | opus_int32 Gain_Q16, /* I */ | ||
102 | opus_int Lambda_Q10, /* I */ | ||
103 | opus_int offset_Q10, /* I */ | ||
104 | opus_int length, /* I Input length */ | ||
105 | opus_int subfr, /* I Subframe number */ | ||
106 | opus_int shapingLPCOrder, /* I Shaping LPC filter order */ | ||
107 | opus_int predictLPCOrder, /* I Prediction filter order */ | ||
108 | opus_int warping_Q16, /* I */ | ||
109 | opus_int nStatesDelayedDecision, /* I Number of states in decision tree */ | ||
110 | opus_int *smpl_buf_idx, /* I/O Index to newest samples in buffers */ | ||
111 | opus_int decisionDelay /* I */ | ||
112 | ); | ||
113 | |||
114 | void silk_NSQ_del_dec_sse4_1( | ||
115 | const silk_encoder_state *psEncC, /* I Encoder State */ | ||
116 | silk_nsq_state *NSQ, /* I/O NSQ state */ | ||
117 | SideInfoIndices *psIndices, /* I/O Quantization Indices */ | ||
118 | const opus_int32 x_Q3[], /* I Prefiltered input signal */ | ||
119 | opus_int8 pulses[], /* O Quantized pulse signal */ | ||
120 | const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ | ||
121 | const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ | ||
122 | const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ | ||
123 | const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ | ||
124 | const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ | ||
125 | const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ | ||
126 | const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ | ||
127 | const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ | ||
128 | const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ | ||
129 | const opus_int LTP_scale_Q14 /* I LTP state scaling */ | ||
130 | ) | ||
131 | { | ||
132 | opus_int i, k, lag, start_idx, LSF_interpolation_flag, Winner_ind, subfr; | ||
133 | opus_int last_smple_idx, smpl_buf_idx, decisionDelay; | ||
134 | const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13; | ||
135 | opus_int16 *pxq; | ||
136 | VARDECL( opus_int32, sLTP_Q15 ); | ||
137 | VARDECL( opus_int16, sLTP ); | ||
138 | opus_int32 HarmShapeFIRPacked_Q14; | ||
139 | opus_int offset_Q10; | ||
140 | opus_int32 RDmin_Q10, Gain_Q10; | ||
141 | VARDECL( opus_int32, x_sc_Q10 ); | ||
142 | VARDECL( opus_int32, delayedGain_Q10 ); | ||
143 | VARDECL( NSQ_del_dec_struct, psDelDec ); | ||
144 | NSQ_del_dec_struct *psDD; | ||
145 | SAVE_STACK; | ||
146 | |||
147 | /* Set unvoiced lag to the previous one, overwrite later for voiced */ | ||
148 | lag = NSQ->lagPrev; | ||
149 | |||
150 | silk_assert( NSQ->prev_gain_Q16 != 0 ); | ||
151 | |||
152 | /* Initialize delayed decision states */ | ||
153 | ALLOC( psDelDec, psEncC->nStatesDelayedDecision, NSQ_del_dec_struct ); | ||
154 | silk_memset( psDelDec, 0, psEncC->nStatesDelayedDecision * sizeof( NSQ_del_dec_struct ) ); | ||
155 | for( k = 0; k < psEncC->nStatesDelayedDecision; k++ ) { | ||
156 | psDD = &psDelDec[ k ]; | ||
157 | psDD->Seed = ( k + psIndices->Seed ) & 3; | ||
158 | psDD->SeedInit = psDD->Seed; | ||
159 | psDD->RD_Q10 = 0; | ||
160 | psDD->LF_AR_Q14 = NSQ->sLF_AR_shp_Q14; | ||
161 | psDD->Shape_Q14[ 0 ] = NSQ->sLTP_shp_Q14[ psEncC->ltp_mem_length - 1 ]; | ||
162 | silk_memcpy( psDD->sLPC_Q14, NSQ->sLPC_Q14, NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) ); | ||
163 | silk_memcpy( psDD->sAR2_Q14, NSQ->sAR2_Q14, sizeof( NSQ->sAR2_Q14 ) ); | ||
164 | } | ||
165 | |||
166 | offset_Q10 = silk_Quantization_Offsets_Q10[ psIndices->signalType >> 1 ][ psIndices->quantOffsetType ]; | ||
167 | smpl_buf_idx = 0; /* index of oldest samples */ | ||
168 | |||
169 | decisionDelay = silk_min_int( DECISION_DELAY, psEncC->subfr_length ); | ||
170 | |||
171 | /* For voiced frames limit the decision delay to lower than the pitch lag */ | ||
172 | if( psIndices->signalType == TYPE_VOICED ) { | ||
173 | for( k = 0; k < psEncC->nb_subfr; k++ ) { | ||
174 | decisionDelay = silk_min_int( decisionDelay, pitchL[ k ] - LTP_ORDER / 2 - 1 ); | ||
175 | } | ||
176 | } else { | ||
177 | if( lag > 0 ) { | ||
178 | decisionDelay = silk_min_int( decisionDelay, lag - LTP_ORDER / 2 - 1 ); | ||
179 | } | ||
180 | } | ||
181 | |||
182 | if( psIndices->NLSFInterpCoef_Q2 == 4 ) { | ||
183 | LSF_interpolation_flag = 0; | ||
184 | } else { | ||
185 | LSF_interpolation_flag = 1; | ||
186 | } | ||
187 | |||
188 | ALLOC( sLTP_Q15, | ||
189 | psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 ); | ||
190 | ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 ); | ||
191 | ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 ); | ||
192 | ALLOC( delayedGain_Q10, DECISION_DELAY, opus_int32 ); | ||
193 | /* Set up pointers to start of sub frame */ | ||
194 | pxq = &NSQ->xq[ psEncC->ltp_mem_length ]; | ||
195 | NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length; | ||
196 | NSQ->sLTP_buf_idx = psEncC->ltp_mem_length; | ||
197 | subfr = 0; | ||
198 | for( k = 0; k < psEncC->nb_subfr; k++ ) { | ||
199 | A_Q12 = &PredCoef_Q12[ ( ( k >> 1 ) | ( 1 - LSF_interpolation_flag ) ) * MAX_LPC_ORDER ]; | ||
200 | B_Q14 = <PCoef_Q14[ k * LTP_ORDER ]; | ||
201 | AR_shp_Q13 = &AR2_Q13[ k * MAX_SHAPE_LPC_ORDER ]; | ||
202 | |||
203 | /* Noise shape parameters */ | ||
204 | silk_assert( HarmShapeGain_Q14[ k ] >= 0 ); | ||
205 | HarmShapeFIRPacked_Q14 = silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 ); | ||
206 | HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 ); | ||
207 | |||
208 | NSQ->rewhite_flag = 0; | ||
209 | if( psIndices->signalType == TYPE_VOICED ) { | ||
210 | /* Voiced */ | ||
211 | lag = pitchL[ k ]; | ||
212 | |||
213 | /* Re-whitening */ | ||
214 | if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) { | ||
215 | if( k == 2 ) { | ||
216 | /* RESET DELAYED DECISIONS */ | ||
217 | /* Find winner */ | ||
218 | RDmin_Q10 = psDelDec[ 0 ].RD_Q10; | ||
219 | Winner_ind = 0; | ||
220 | for( i = 1; i < psEncC->nStatesDelayedDecision; i++ ) { | ||
221 | if( psDelDec[ i ].RD_Q10 < RDmin_Q10 ) { | ||
222 | RDmin_Q10 = psDelDec[ i ].RD_Q10; | ||
223 | Winner_ind = i; | ||
224 | } | ||
225 | } | ||
226 | for( i = 0; i < psEncC->nStatesDelayedDecision; i++ ) { | ||
227 | if( i != Winner_ind ) { | ||
228 | psDelDec[ i ].RD_Q10 += ( silk_int32_MAX >> 4 ); | ||
229 | silk_assert( psDelDec[ i ].RD_Q10 >= 0 ); | ||
230 | } | ||
231 | } | ||
232 | |||
233 | /* Copy final part of signals from winner state to output and long-term filter states */ | ||
234 | psDD = &psDelDec[ Winner_ind ]; | ||
235 | last_smple_idx = smpl_buf_idx + decisionDelay; | ||
236 | for( i = 0; i < decisionDelay; i++ ) { | ||
237 | last_smple_idx = ( last_smple_idx - 1 ) % DECISION_DELAY; | ||
238 | if( last_smple_idx < 0 ) last_smple_idx += DECISION_DELAY; | ||
239 | pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 ); | ||
240 | pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( | ||
241 | silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gains_Q16[ 1 ] ), 14 ) ); | ||
242 | NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q14[ last_smple_idx ]; | ||
243 | } | ||
244 | |||
245 | subfr = 0; | ||
246 | } | ||
247 | |||
248 | /* Rewhiten with new A coefs */ | ||
249 | start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2; | ||
250 | celt_assert( start_idx > 0 ); | ||
251 | |||
252 | silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ], | ||
253 | A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder, psEncC->arch ); | ||
254 | |||
255 | NSQ->sLTP_buf_idx = psEncC->ltp_mem_length; | ||
256 | NSQ->rewhite_flag = 1; | ||
257 | } | ||
258 | } | ||
259 | |||
260 | silk_nsq_del_dec_scale_states_sse4_1( psEncC, NSQ, psDelDec, x_Q3, x_sc_Q10, sLTP, sLTP_Q15, k, | ||
261 | psEncC->nStatesDelayedDecision, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType, decisionDelay ); | ||
262 | |||
263 | silk_noise_shape_quantizer_del_dec_sse4_1( NSQ, psDelDec, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15, | ||
264 | delayedGain_Q10, A_Q12, B_Q14, AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], | ||
265 | Gains_Q16[ k ], Lambda_Q10, offset_Q10, psEncC->subfr_length, subfr++, psEncC->shapingLPCOrder, | ||
266 | psEncC->predictLPCOrder, psEncC->warping_Q16, psEncC->nStatesDelayedDecision, &smpl_buf_idx, decisionDelay ); | ||
267 | |||
268 | x_Q3 += psEncC->subfr_length; | ||
269 | pulses += psEncC->subfr_length; | ||
270 | pxq += psEncC->subfr_length; | ||
271 | } | ||
272 | |||
273 | /* Find winner */ | ||
274 | RDmin_Q10 = psDelDec[ 0 ].RD_Q10; | ||
275 | Winner_ind = 0; | ||
276 | for( k = 1; k < psEncC->nStatesDelayedDecision; k++ ) { | ||
277 | if( psDelDec[ k ].RD_Q10 < RDmin_Q10 ) { | ||
278 | RDmin_Q10 = psDelDec[ k ].RD_Q10; | ||
279 | Winner_ind = k; | ||
280 | } | ||
281 | } | ||
282 | |||
283 | /* Copy final part of signals from winner state to output and long-term filter states */ | ||
284 | psDD = &psDelDec[ Winner_ind ]; | ||
285 | psIndices->Seed = psDD->SeedInit; | ||
286 | last_smple_idx = smpl_buf_idx + decisionDelay; | ||
287 | Gain_Q10 = silk_RSHIFT32( Gains_Q16[ psEncC->nb_subfr - 1 ], 6 ); | ||
288 | for( i = 0; i < decisionDelay; i++ ) { | ||
289 | last_smple_idx = ( last_smple_idx - 1 ) % DECISION_DELAY; | ||
290 | if( last_smple_idx < 0 ) last_smple_idx += DECISION_DELAY; | ||
291 | pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 ); | ||
292 | pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( | ||
293 | silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gain_Q10 ), 8 ) ); | ||
294 | NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q14[ last_smple_idx ]; | ||
295 | } | ||
296 | silk_memcpy( NSQ->sLPC_Q14, &psDD->sLPC_Q14[ psEncC->subfr_length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) ); | ||
297 | silk_memcpy( NSQ->sAR2_Q14, psDD->sAR2_Q14, sizeof( psDD->sAR2_Q14 ) ); | ||
298 | |||
299 | /* Update states */ | ||
300 | NSQ->sLF_AR_shp_Q14 = psDD->LF_AR_Q14; | ||
301 | NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ]; | ||
302 | |||
303 | /* Save quantized speech signal */ | ||
304 | silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) ); | ||
305 | silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) ); | ||
306 | RESTORE_STACK; | ||
307 | } | ||
308 | |||
309 | /******************************************/ | ||
310 | /* Noise shape quantizer for one subframe */ | ||
311 | /******************************************/ | ||
312 | static OPUS_INLINE void silk_noise_shape_quantizer_del_dec_sse4_1( | ||
313 | silk_nsq_state *NSQ, /* I/O NSQ state */ | ||
314 | NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ | ||
315 | opus_int signalType, /* I Signal type */ | ||
316 | const opus_int32 x_Q10[], /* I */ | ||
317 | opus_int8 pulses[], /* O */ | ||
318 | opus_int16 xq[], /* O */ | ||
319 | opus_int32 sLTP_Q15[], /* I/O LTP filter state */ | ||
320 | opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */ | ||
321 | const opus_int16 a_Q12[], /* I Short term prediction coefs */ | ||
322 | const opus_int16 b_Q14[], /* I Long term prediction coefs */ | ||
323 | const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */ | ||
324 | opus_int lag, /* I Pitch lag */ | ||
325 | opus_int32 HarmShapeFIRPacked_Q14, /* I */ | ||
326 | opus_int Tilt_Q14, /* I Spectral tilt */ | ||
327 | opus_int32 LF_shp_Q14, /* I */ | ||
328 | opus_int32 Gain_Q16, /* I */ | ||
329 | opus_int Lambda_Q10, /* I */ | ||
330 | opus_int offset_Q10, /* I */ | ||
331 | opus_int length, /* I Input length */ | ||
332 | opus_int subfr, /* I Subframe number */ | ||
333 | opus_int shapingLPCOrder, /* I Shaping LPC filter order */ | ||
334 | opus_int predictLPCOrder, /* I Prediction filter order */ | ||
335 | opus_int warping_Q16, /* I */ | ||
336 | opus_int nStatesDelayedDecision, /* I Number of states in decision tree */ | ||
337 | opus_int *smpl_buf_idx, /* I/O Index to newest samples in buffers */ | ||
338 | opus_int decisionDelay /* I */ | ||
339 | ) | ||
340 | { | ||
341 | opus_int i, j, k, Winner_ind, RDmin_ind, RDmax_ind, last_smple_idx; | ||
342 | opus_int32 Winner_rand_state; | ||
343 | opus_int32 LTP_pred_Q14, LPC_pred_Q14, n_AR_Q14, n_LTP_Q14; | ||
344 | opus_int32 n_LF_Q14, r_Q10, rr_Q10, rd1_Q10, rd2_Q10, RDmin_Q10, RDmax_Q10; | ||
345 | opus_int32 q1_Q0, q1_Q10, q2_Q10, exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10; | ||
346 | opus_int32 tmp1, tmp2, sLF_AR_shp_Q14; | ||
347 | opus_int32 *pred_lag_ptr, *shp_lag_ptr, *psLPC_Q14; | ||
348 | VARDECL( NSQ_sample_pair, psSampleState ); | ||
349 | NSQ_del_dec_struct *psDD; | ||
350 | NSQ_sample_struct *psSS; | ||
351 | |||
352 | __m128i a_Q12_0123, a_Q12_4567, a_Q12_89AB, a_Q12_CDEF; | ||
353 | __m128i b_Q12_0123, b_sr_Q12_0123; | ||
354 | SAVE_STACK; | ||
355 | |||
356 | celt_assert( nStatesDelayedDecision > 0 ); | ||
357 | ALLOC( psSampleState, nStatesDelayedDecision, NSQ_sample_pair ); | ||
358 | |||
359 | shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ]; | ||
360 | pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ]; | ||
361 | Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 ); | ||
362 | |||
363 | a_Q12_0123 = OP_CVTEPI16_EPI32_M64( a_Q12 ); | ||
364 | a_Q12_4567 = OP_CVTEPI16_EPI32_M64( a_Q12 + 4 ); | ||
365 | |||
366 | if( opus_likely( predictLPCOrder == 16 ) ) { | ||
367 | a_Q12_89AB = OP_CVTEPI16_EPI32_M64( a_Q12 + 8 ); | ||
368 | a_Q12_CDEF = OP_CVTEPI16_EPI32_M64( a_Q12 + 12 ); | ||
369 | } | ||
370 | |||
371 | if( signalType == TYPE_VOICED ){ | ||
372 | b_Q12_0123 = OP_CVTEPI16_EPI32_M64( b_Q14 ); | ||
373 | b_sr_Q12_0123 = _mm_shuffle_epi32( b_Q12_0123, _MM_SHUFFLE( 0, 3, 2, 1 ) ); /* equal shift right 4 bytes */ | ||
374 | } | ||
375 | for( i = 0; i < length; i++ ) { | ||
376 | /* Perform common calculations used in all states */ | ||
377 | |||
378 | /* Long-term prediction */ | ||
379 | if( signalType == TYPE_VOICED ) { | ||
380 | /* Unrolled loop */ | ||
381 | /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ | ||
382 | LTP_pred_Q14 = 2; | ||
383 | { | ||
384 | __m128i tmpa, tmpb, pred_lag_ptr_tmp; | ||
385 | pred_lag_ptr_tmp = _mm_loadu_si128( (__m128i *)(&pred_lag_ptr[ -3 ] ) ); | ||
386 | pred_lag_ptr_tmp = _mm_shuffle_epi32( pred_lag_ptr_tmp, 0x1B ); | ||
387 | tmpa = _mm_mul_epi32( pred_lag_ptr_tmp, b_Q12_0123 ); | ||
388 | tmpa = _mm_srli_si128( tmpa, 2 ); | ||
389 | |||
390 | pred_lag_ptr_tmp = _mm_shuffle_epi32( pred_lag_ptr_tmp, _MM_SHUFFLE( 0, 3, 2, 1 ) );/* equal shift right 4 bytes */ | ||
391 | pred_lag_ptr_tmp = _mm_mul_epi32( pred_lag_ptr_tmp, b_sr_Q12_0123 ); | ||
392 | pred_lag_ptr_tmp = _mm_srli_si128( pred_lag_ptr_tmp, 2 ); | ||
393 | pred_lag_ptr_tmp = _mm_add_epi32( pred_lag_ptr_tmp, tmpa ); | ||
394 | |||
395 | tmpb = _mm_shuffle_epi32( pred_lag_ptr_tmp, _MM_SHUFFLE( 0, 0, 3, 2 ) );/* equal shift right 8 bytes */ | ||
396 | pred_lag_ptr_tmp = _mm_add_epi32( pred_lag_ptr_tmp, tmpb ); | ||
397 | LTP_pred_Q14 += _mm_cvtsi128_si32( pred_lag_ptr_tmp ); | ||
398 | |||
399 | LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], b_Q14[ 4 ] ); | ||
400 | LTP_pred_Q14 = silk_LSHIFT( LTP_pred_Q14, 1 ); /* Q13 -> Q14 */ | ||
401 | pred_lag_ptr++; | ||
402 | } | ||
403 | } else { | ||
404 | LTP_pred_Q14 = 0; | ||
405 | } | ||
406 | |||
407 | /* Long-term shaping */ | ||
408 | if( lag > 0 ) { | ||
409 | /* Symmetric, packed FIR coefficients */ | ||
410 | n_LTP_Q14 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 ); | ||
411 | n_LTP_Q14 = silk_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 ); | ||
412 | n_LTP_Q14 = silk_SUB_LSHIFT32( LTP_pred_Q14, n_LTP_Q14, 2 ); /* Q12 -> Q14 */ | ||
413 | shp_lag_ptr++; | ||
414 | } else { | ||
415 | n_LTP_Q14 = 0; | ||
416 | } | ||
417 | { | ||
418 | __m128i tmpa, tmpb, psLPC_Q14_tmp, a_Q12_tmp; | ||
419 | |||
420 | for( k = 0; k < nStatesDelayedDecision; k++ ) { | ||
421 | /* Delayed decision state */ | ||
422 | psDD = &psDelDec[ k ]; | ||
423 | |||
424 | /* Sample state */ | ||
425 | psSS = psSampleState[ k ]; | ||
426 | |||
427 | /* Generate dither */ | ||
428 | psDD->Seed = silk_RAND( psDD->Seed ); | ||
429 | |||
430 | /* Pointer used in short term prediction and shaping */ | ||
431 | psLPC_Q14 = &psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 + i ]; | ||
432 | /* Short-term prediction */ | ||
433 | silk_assert( predictLPCOrder == 10 || predictLPCOrder == 16 ); | ||
434 | /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ | ||
435 | LPC_pred_Q14 = silk_RSHIFT( predictLPCOrder, 1 ); | ||
436 | |||
437 | tmpb = _mm_setzero_si128(); | ||
438 | |||
439 | /* step 1 */ | ||
440 | psLPC_Q14_tmp = _mm_loadu_si128( (__m128i *)(&psLPC_Q14[ -3 ] ) ); /* -3, -2 , -1, 0 */ | ||
441 | psLPC_Q14_tmp = _mm_shuffle_epi32( psLPC_Q14_tmp, 0x1B ); /* 0, -1, -2, -3 */ | ||
442 | tmpa = _mm_mul_epi32( psLPC_Q14_tmp, a_Q12_0123 ); /* 0, -1, -2, -3 * 0123 -> 0*0, 2*-2 */ | ||
443 | |||
444 | tmpa = _mm_srli_epi64( tmpa, 16 ); | ||
445 | tmpb = _mm_add_epi32( tmpb, tmpa ); | ||
446 | |||
447 | psLPC_Q14_tmp = _mm_shuffle_epi32( psLPC_Q14_tmp, _MM_SHUFFLE( 0, 3, 2, 1 ) ); /* equal shift right 4 bytes */ | ||
448 | a_Q12_tmp = _mm_shuffle_epi32( a_Q12_0123, _MM_SHUFFLE(0, 3, 2, 1 ) ); /* equal shift right 4 bytes */ | ||
449 | psLPC_Q14_tmp = _mm_mul_epi32( psLPC_Q14_tmp, a_Q12_tmp ); /* 1*-1, 3*-3 */ | ||
450 | psLPC_Q14_tmp = _mm_srli_epi64( psLPC_Q14_tmp, 16 ); | ||
451 | tmpb = _mm_add_epi32( tmpb, psLPC_Q14_tmp ); | ||
452 | |||
453 | /* step 2 */ | ||
454 | psLPC_Q14_tmp = _mm_loadu_si128( (__m128i *)(&psLPC_Q14[ -7 ] ) ); | ||
455 | psLPC_Q14_tmp = _mm_shuffle_epi32( psLPC_Q14_tmp, 0x1B ); | ||
456 | tmpa = _mm_mul_epi32( psLPC_Q14_tmp, a_Q12_4567 ); | ||
457 | tmpa = _mm_srli_epi64( tmpa, 16 ); | ||
458 | tmpb = _mm_add_epi32( tmpb, tmpa ); | ||
459 | |||
460 | psLPC_Q14_tmp = _mm_shuffle_epi32( psLPC_Q14_tmp, _MM_SHUFFLE( 0, 3, 2, 1 ) ); /* equal shift right 4 bytes */ | ||
461 | a_Q12_tmp = _mm_shuffle_epi32( a_Q12_4567, _MM_SHUFFLE(0, 3, 2, 1 ) ); /* equal shift right 4 bytes */ | ||
462 | psLPC_Q14_tmp = _mm_mul_epi32( psLPC_Q14_tmp, a_Q12_tmp ); | ||
463 | psLPC_Q14_tmp = _mm_srli_epi64( psLPC_Q14_tmp, 16 ); | ||
464 | tmpb = _mm_add_epi32( tmpb, psLPC_Q14_tmp ); | ||
465 | |||
466 | if ( opus_likely( predictLPCOrder == 16 ) ) | ||
467 | { | ||
468 | /* step 3 */ | ||
469 | psLPC_Q14_tmp = _mm_loadu_si128( (__m128i *)(&psLPC_Q14[ -11 ] ) ); | ||
470 | psLPC_Q14_tmp = _mm_shuffle_epi32( psLPC_Q14_tmp, 0x1B ); | ||
471 | tmpa = _mm_mul_epi32( psLPC_Q14_tmp, a_Q12_89AB ); | ||
472 | tmpa = _mm_srli_epi64( tmpa, 16 ); | ||
473 | tmpb = _mm_add_epi32( tmpb, tmpa ); | ||
474 | |||
475 | psLPC_Q14_tmp = _mm_shuffle_epi32( psLPC_Q14_tmp, _MM_SHUFFLE( 0, 3, 2, 1 ) ); /* equal shift right 4 bytes */ | ||
476 | a_Q12_tmp = _mm_shuffle_epi32( a_Q12_89AB, _MM_SHUFFLE(0, 3, 2, 1 ) );/* equal shift right 4 bytes */ | ||
477 | psLPC_Q14_tmp = _mm_mul_epi32( psLPC_Q14_tmp, a_Q12_tmp ); | ||
478 | psLPC_Q14_tmp = _mm_srli_epi64( psLPC_Q14_tmp, 16 ); | ||
479 | tmpb = _mm_add_epi32( tmpb, psLPC_Q14_tmp ); | ||
480 | |||
481 | /* setp 4 */ | ||
482 | psLPC_Q14_tmp = _mm_loadu_si128( (__m128i *)(&psLPC_Q14[ -15 ] ) ); | ||
483 | psLPC_Q14_tmp = _mm_shuffle_epi32( psLPC_Q14_tmp, 0x1B ); | ||
484 | tmpa = _mm_mul_epi32( psLPC_Q14_tmp, a_Q12_CDEF ); | ||
485 | tmpa = _mm_srli_epi64( tmpa, 16 ); | ||
486 | tmpb = _mm_add_epi32( tmpb, tmpa ); | ||
487 | |||
488 | psLPC_Q14_tmp = _mm_shuffle_epi32( psLPC_Q14_tmp, _MM_SHUFFLE( 0, 3, 2, 1 ) ); /* equal shift right 4 bytes */ | ||
489 | a_Q12_tmp = _mm_shuffle_epi32( a_Q12_CDEF, _MM_SHUFFLE(0, 3, 2, 1 ) ); /* equal shift right 4 bytes */ | ||
490 | psLPC_Q14_tmp = _mm_mul_epi32( psLPC_Q14_tmp, a_Q12_tmp ); | ||
491 | psLPC_Q14_tmp = _mm_srli_epi64( psLPC_Q14_tmp, 16 ); | ||
492 | tmpb = _mm_add_epi32( tmpb, psLPC_Q14_tmp ); | ||
493 | |||
494 | /* add at last */ | ||
495 | /* equal shift right 8 bytes*/ | ||
496 | tmpa = _mm_shuffle_epi32( tmpb, _MM_SHUFFLE( 0, 0, 3, 2 ) ); | ||
497 | tmpb = _mm_add_epi32( tmpb, tmpa ); | ||
498 | LPC_pred_Q14 += _mm_cvtsi128_si32( tmpb ); | ||
499 | } | ||
500 | else | ||
501 | { | ||
502 | /* add at last */ | ||
503 | tmpa = _mm_shuffle_epi32( tmpb, _MM_SHUFFLE( 0, 0, 3, 2 ) ); /* equal shift right 8 bytes*/ | ||
504 | tmpb = _mm_add_epi32( tmpb, tmpa ); | ||
505 | LPC_pred_Q14 += _mm_cvtsi128_si32( tmpb ); | ||
506 | |||
507 | LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -8 ], a_Q12[ 8 ] ); | ||
508 | LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -9 ], a_Q12[ 9 ] ); | ||
509 | } | ||
510 | |||
511 | LPC_pred_Q14 = silk_LSHIFT( LPC_pred_Q14, 4 ); /* Q10 -> Q14 */ | ||
512 | |||
513 | /* Noise shape feedback */ | ||
514 | silk_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */ | ||
515 | /* Output of lowpass section */ | ||
516 | tmp2 = silk_SMLAWB( psLPC_Q14[ 0 ], psDD->sAR2_Q14[ 0 ], warping_Q16 ); | ||
517 | /* Output of allpass section */ | ||
518 | tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ 0 ], psDD->sAR2_Q14[ 1 ] - tmp2, warping_Q16 ); | ||
519 | psDD->sAR2_Q14[ 0 ] = tmp2; | ||
520 | n_AR_Q14 = silk_RSHIFT( shapingLPCOrder, 1 ); | ||
521 | n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp2, AR_shp_Q13[ 0 ] ); | ||
522 | /* Loop over allpass sections */ | ||
523 | for( j = 2; j < shapingLPCOrder; j += 2 ) { | ||
524 | /* Output of allpass section */ | ||
525 | tmp2 = silk_SMLAWB( psDD->sAR2_Q14[ j - 1 ], psDD->sAR2_Q14[ j + 0 ] - tmp1, warping_Q16 ); | ||
526 | psDD->sAR2_Q14[ j - 1 ] = tmp1; | ||
527 | n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp1, AR_shp_Q13[ j - 1 ] ); | ||
528 | /* Output of allpass section */ | ||
529 | tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ j + 0 ], psDD->sAR2_Q14[ j + 1 ] - tmp2, warping_Q16 ); | ||
530 | psDD->sAR2_Q14[ j + 0 ] = tmp2; | ||
531 | n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp2, AR_shp_Q13[ j ] ); | ||
532 | } | ||
533 | psDD->sAR2_Q14[ shapingLPCOrder - 1 ] = tmp1; | ||
534 | n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp1, AR_shp_Q13[ shapingLPCOrder - 1 ] ); | ||
535 | |||
536 | n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 1 ); /* Q11 -> Q12 */ | ||
537 | n_AR_Q14 = silk_SMLAWB( n_AR_Q14, psDD->LF_AR_Q14, Tilt_Q14 ); /* Q12 */ | ||
538 | n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 2 ); /* Q12 -> Q14 */ | ||
539 | |||
540 | n_LF_Q14 = silk_SMULWB( psDD->Shape_Q14[ *smpl_buf_idx ], LF_shp_Q14 ); /* Q12 */ | ||
541 | n_LF_Q14 = silk_SMLAWT( n_LF_Q14, psDD->LF_AR_Q14, LF_shp_Q14 ); /* Q12 */ | ||
542 | n_LF_Q14 = silk_LSHIFT( n_LF_Q14, 2 ); /* Q12 -> Q14 */ | ||
543 | |||
544 | /* Input minus prediction plus noise feedback */ | ||
545 | /* r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP */ | ||
546 | tmp1 = silk_ADD32( n_AR_Q14, n_LF_Q14 ); /* Q14 */ | ||
547 | tmp2 = silk_ADD32( n_LTP_Q14, LPC_pred_Q14 ); /* Q13 */ | ||
548 | tmp1 = silk_SUB32( tmp2, tmp1 ); /* Q13 */ | ||
549 | tmp1 = silk_RSHIFT_ROUND( tmp1, 4 ); /* Q10 */ | ||
550 | |||
551 | r_Q10 = silk_SUB32( x_Q10[ i ], tmp1 ); /* residual error Q10 */ | ||
552 | |||
553 | /* Flip sign depending on dither */ | ||
554 | if ( psDD->Seed < 0 ) { | ||
555 | r_Q10 = -r_Q10; | ||
556 | } | ||
557 | r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 ); | ||
558 | |||
559 | /* Find two quantization level candidates and measure their rate-distortion */ | ||
560 | q1_Q10 = silk_SUB32( r_Q10, offset_Q10 ); | ||
561 | q1_Q0 = silk_RSHIFT( q1_Q10, 10 ); | ||
562 | if( q1_Q0 > 0 ) { | ||
563 | q1_Q10 = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 ); | ||
564 | q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 ); | ||
565 | q2_Q10 = silk_ADD32( q1_Q10, 1024 ); | ||
566 | rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 ); | ||
567 | rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 ); | ||
568 | } else if( q1_Q0 == 0 ) { | ||
569 | q1_Q10 = offset_Q10; | ||
570 | q2_Q10 = silk_ADD32( q1_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 ); | ||
571 | rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 ); | ||
572 | rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 ); | ||
573 | } else if( q1_Q0 == -1 ) { | ||
574 | q2_Q10 = offset_Q10; | ||
575 | q1_Q10 = silk_SUB32( q2_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 ); | ||
576 | rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 ); | ||
577 | rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 ); | ||
578 | } else { /* q1_Q0 < -1 */ | ||
579 | q1_Q10 = silk_ADD32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 ); | ||
580 | q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 ); | ||
581 | q2_Q10 = silk_ADD32( q1_Q10, 1024 ); | ||
582 | rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 ); | ||
583 | rd2_Q10 = silk_SMULBB( -q2_Q10, Lambda_Q10 ); | ||
584 | } | ||
585 | rr_Q10 = silk_SUB32( r_Q10, q1_Q10 ); | ||
586 | rd1_Q10 = silk_RSHIFT( silk_SMLABB( rd1_Q10, rr_Q10, rr_Q10 ), 10 ); | ||
587 | rr_Q10 = silk_SUB32( r_Q10, q2_Q10 ); | ||
588 | rd2_Q10 = silk_RSHIFT( silk_SMLABB( rd2_Q10, rr_Q10, rr_Q10 ), 10 ); | ||
589 | |||
590 | if( rd1_Q10 < rd2_Q10 ) { | ||
591 | psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 ); | ||
592 | psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 ); | ||
593 | psSS[ 0 ].Q_Q10 = q1_Q10; | ||
594 | psSS[ 1 ].Q_Q10 = q2_Q10; | ||
595 | } else { | ||
596 | psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 ); | ||
597 | psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 ); | ||
598 | psSS[ 0 ].Q_Q10 = q2_Q10; | ||
599 | psSS[ 1 ].Q_Q10 = q1_Q10; | ||
600 | } | ||
601 | |||
602 | /* Update states for best quantization */ | ||
603 | |||
604 | /* Quantized excitation */ | ||
605 | exc_Q14 = silk_LSHIFT32( psSS[ 0 ].Q_Q10, 4 ); | ||
606 | if ( psDD->Seed < 0 ) { | ||
607 | exc_Q14 = -exc_Q14; | ||
608 | } | ||
609 | |||
610 | /* Add predictions */ | ||
611 | LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 ); | ||
612 | xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 ); | ||
613 | |||
614 | /* Update states */ | ||
615 | sLF_AR_shp_Q14 = silk_SUB32( xq_Q14, n_AR_Q14 ); | ||
616 | psSS[ 0 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 ); | ||
617 | psSS[ 0 ].LF_AR_Q14 = sLF_AR_shp_Q14; | ||
618 | psSS[ 0 ].LPC_exc_Q14 = LPC_exc_Q14; | ||
619 | psSS[ 0 ].xq_Q14 = xq_Q14; | ||
620 | |||
621 | /* Update states for second best quantization */ | ||
622 | |||
623 | /* Quantized excitation */ | ||
624 | exc_Q14 = silk_LSHIFT32( psSS[ 1 ].Q_Q10, 4 ); | ||
625 | if ( psDD->Seed < 0 ) { | ||
626 | exc_Q14 = -exc_Q14; | ||
627 | } | ||
628 | |||
629 | |||
630 | /* Add predictions */ | ||
631 | LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 ); | ||
632 | xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 ); | ||
633 | |||
634 | /* Update states */ | ||
635 | sLF_AR_shp_Q14 = silk_SUB32( xq_Q14, n_AR_Q14 ); | ||
636 | psSS[ 1 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 ); | ||
637 | psSS[ 1 ].LF_AR_Q14 = sLF_AR_shp_Q14; | ||
638 | psSS[ 1 ].LPC_exc_Q14 = LPC_exc_Q14; | ||
639 | psSS[ 1 ].xq_Q14 = xq_Q14; | ||
640 | } | ||
641 | } | ||
642 | *smpl_buf_idx = ( *smpl_buf_idx - 1 ) % DECISION_DELAY; | ||
643 | if( *smpl_buf_idx < 0 ) *smpl_buf_idx += DECISION_DELAY; | ||
644 | last_smple_idx = ( *smpl_buf_idx + decisionDelay ) % DECISION_DELAY; | ||
645 | |||
646 | /* Find winner */ | ||
647 | RDmin_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10; | ||
648 | Winner_ind = 0; | ||
649 | for( k = 1; k < nStatesDelayedDecision; k++ ) { | ||
650 | if( psSampleState[ k ][ 0 ].RD_Q10 < RDmin_Q10 ) { | ||
651 | RDmin_Q10 = psSampleState[ k ][ 0 ].RD_Q10; | ||
652 | Winner_ind = k; | ||
653 | } | ||
654 | } | ||
655 | |||
656 | /* Increase RD values of expired states */ | ||
657 | Winner_rand_state = psDelDec[ Winner_ind ].RandState[ last_smple_idx ]; | ||
658 | for( k = 0; k < nStatesDelayedDecision; k++ ) { | ||
659 | if( psDelDec[ k ].RandState[ last_smple_idx ] != Winner_rand_state ) { | ||
660 | psSampleState[ k ][ 0 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 0 ].RD_Q10, silk_int32_MAX >> 4 ); | ||
661 | psSampleState[ k ][ 1 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 1 ].RD_Q10, silk_int32_MAX >> 4 ); | ||
662 | silk_assert( psSampleState[ k ][ 0 ].RD_Q10 >= 0 ); | ||
663 | } | ||
664 | } | ||
665 | |||
666 | /* Find worst in first set and best in second set */ | ||
667 | RDmax_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10; | ||
668 | RDmin_Q10 = psSampleState[ 0 ][ 1 ].RD_Q10; | ||
669 | RDmax_ind = 0; | ||
670 | RDmin_ind = 0; | ||
671 | for( k = 1; k < nStatesDelayedDecision; k++ ) { | ||
672 | /* find worst in first set */ | ||
673 | if( psSampleState[ k ][ 0 ].RD_Q10 > RDmax_Q10 ) { | ||
674 | RDmax_Q10 = psSampleState[ k ][ 0 ].RD_Q10; | ||
675 | RDmax_ind = k; | ||
676 | } | ||
677 | /* find best in second set */ | ||
678 | if( psSampleState[ k ][ 1 ].RD_Q10 < RDmin_Q10 ) { | ||
679 | RDmin_Q10 = psSampleState[ k ][ 1 ].RD_Q10; | ||
680 | RDmin_ind = k; | ||
681 | } | ||
682 | } | ||
683 | |||
684 | /* Replace a state if best from second set outperforms worst in first set */ | ||
685 | if( RDmin_Q10 < RDmax_Q10 ) { | ||
686 | silk_memcpy( ( (opus_int32 *)&psDelDec[ RDmax_ind ] ) + i, | ||
687 | ( (opus_int32 *)&psDelDec[ RDmin_ind ] ) + i, sizeof( NSQ_del_dec_struct ) - i * sizeof( opus_int32) ); | ||
688 | silk_memcpy( &psSampleState[ RDmax_ind ][ 0 ], &psSampleState[ RDmin_ind ][ 1 ], sizeof( NSQ_sample_struct ) ); | ||
689 | } | ||
690 | |||
691 | /* Write samples from winner to output and long-term filter states */ | ||
692 | psDD = &psDelDec[ Winner_ind ]; | ||
693 | if( subfr > 0 || i >= decisionDelay ) { | ||
694 | pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 ); | ||
695 | xq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( | ||
696 | silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], delayedGain_Q10[ last_smple_idx ] ), 8 ) ); | ||
697 | NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay ] = psDD->Shape_Q14[ last_smple_idx ]; | ||
698 | sLTP_Q15[ NSQ->sLTP_buf_idx - decisionDelay ] = psDD->Pred_Q15[ last_smple_idx ]; | ||
699 | } | ||
700 | NSQ->sLTP_shp_buf_idx++; | ||
701 | NSQ->sLTP_buf_idx++; | ||
702 | |||
703 | /* Update states */ | ||
704 | for( k = 0; k < nStatesDelayedDecision; k++ ) { | ||
705 | psDD = &psDelDec[ k ]; | ||
706 | psSS = &psSampleState[ k ][ 0 ]; | ||
707 | psDD->LF_AR_Q14 = psSS->LF_AR_Q14; | ||
708 | psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH + i ] = psSS->xq_Q14; | ||
709 | psDD->Xq_Q14[ *smpl_buf_idx ] = psSS->xq_Q14; | ||
710 | psDD->Q_Q10[ *smpl_buf_idx ] = psSS->Q_Q10; | ||
711 | psDD->Pred_Q15[ *smpl_buf_idx ] = silk_LSHIFT32( psSS->LPC_exc_Q14, 1 ); | ||
712 | psDD->Shape_Q14[ *smpl_buf_idx ] = psSS->sLTP_shp_Q14; | ||
713 | psDD->Seed = silk_ADD32_ovflw( psDD->Seed, silk_RSHIFT_ROUND( psSS->Q_Q10, 10 ) ); | ||
714 | psDD->RandState[ *smpl_buf_idx ] = psDD->Seed; | ||
715 | psDD->RD_Q10 = psSS->RD_Q10; | ||
716 | } | ||
717 | delayedGain_Q10[ *smpl_buf_idx ] = Gain_Q10; | ||
718 | } | ||
719 | /* Update LPC states */ | ||
720 | for( k = 0; k < nStatesDelayedDecision; k++ ) { | ||
721 | psDD = &psDelDec[ k ]; | ||
722 | silk_memcpy( psDD->sLPC_Q14, &psDD->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) ); | ||
723 | } | ||
724 | RESTORE_STACK; | ||
725 | } | ||
726 | |||
727 | static OPUS_INLINE void silk_nsq_del_dec_scale_states_sse4_1( | ||
728 | const silk_encoder_state *psEncC, /* I Encoder State */ | ||
729 | silk_nsq_state *NSQ, /* I/O NSQ state */ | ||
730 | NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ | ||
731 | const opus_int32 x_Q3[], /* I Input in Q3 */ | ||
732 | opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */ | ||
733 | const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */ | ||
734 | opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ | ||
735 | opus_int subfr, /* I Subframe number */ | ||
736 | opus_int nStatesDelayedDecision, /* I Number of del dec states */ | ||
737 | const opus_int LTP_scale_Q14, /* I LTP state scaling */ | ||
738 | const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ | ||
739 | const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */ | ||
740 | const opus_int signal_type, /* I Signal type */ | ||
741 | const opus_int decisionDelay /* I Decision delay */ | ||
742 | ) | ||
743 | { | ||
744 | opus_int i, k, lag; | ||
745 | opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q23; | ||
746 | NSQ_del_dec_struct *psDD; | ||
747 | __m128i xmm_inv_gain_Q23, xmm_x_Q3_x2x0, xmm_x_Q3_x3x1; | ||
748 | |||
749 | lag = pitchL[ subfr ]; | ||
750 | inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 ); | ||
751 | |||
752 | silk_assert( inv_gain_Q31 != 0 ); | ||
753 | |||
754 | /* Calculate gain adjustment factor */ | ||
755 | if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) { | ||
756 | gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 ); | ||
757 | } else { | ||
758 | gain_adj_Q16 = (opus_int32)1 << 16; | ||
759 | } | ||
760 | |||
761 | /* Scale input */ | ||
762 | inv_gain_Q23 = silk_RSHIFT_ROUND( inv_gain_Q31, 8 ); | ||
763 | |||
764 | /* prepare inv_gain_Q23 in packed 4 32-bits */ | ||
765 | xmm_inv_gain_Q23 = _mm_set1_epi32(inv_gain_Q23); | ||
766 | |||
767 | for( i = 0; i < psEncC->subfr_length - 3; i += 4 ) { | ||
768 | xmm_x_Q3_x2x0 = _mm_loadu_si128( (__m128i *)(&(x_Q3[ i ] ) ) ); | ||
769 | /* equal shift right 4 bytes*/ | ||
770 | xmm_x_Q3_x3x1 = _mm_shuffle_epi32( xmm_x_Q3_x2x0, _MM_SHUFFLE( 0, 3, 2, 1 ) ); | ||
771 | |||
772 | xmm_x_Q3_x2x0 = _mm_mul_epi32( xmm_x_Q3_x2x0, xmm_inv_gain_Q23 ); | ||
773 | xmm_x_Q3_x3x1 = _mm_mul_epi32( xmm_x_Q3_x3x1, xmm_inv_gain_Q23 ); | ||
774 | |||
775 | xmm_x_Q3_x2x0 = _mm_srli_epi64( xmm_x_Q3_x2x0, 16 ); | ||
776 | xmm_x_Q3_x3x1 = _mm_slli_epi64( xmm_x_Q3_x3x1, 16 ); | ||
777 | |||
778 | xmm_x_Q3_x2x0 = _mm_blend_epi16( xmm_x_Q3_x2x0, xmm_x_Q3_x3x1, 0xCC ); | ||
779 | |||
780 | _mm_storeu_si128( (__m128i *)(&(x_sc_Q10[ i ])), xmm_x_Q3_x2x0 ); | ||
781 | } | ||
782 | |||
783 | for( ; i < psEncC->subfr_length; i++ ) { | ||
784 | x_sc_Q10[ i ] = silk_SMULWW( x_Q3[ i ], inv_gain_Q23 ); | ||
785 | } | ||
786 | |||
787 | /* Save inverse gain */ | ||
788 | NSQ->prev_gain_Q16 = Gains_Q16[ subfr ]; | ||
789 | |||
790 | /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */ | ||
791 | if( NSQ->rewhite_flag ) { | ||
792 | if( subfr == 0 ) { | ||
793 | /* Do LTP downscaling */ | ||
794 | inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 ); | ||
795 | } | ||
796 | for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) { | ||
797 | silk_assert( i < MAX_FRAME_LENGTH ); | ||
798 | sLTP_Q15[ i ] = silk_SMULWB( inv_gain_Q31, sLTP[ i ] ); | ||
799 | } | ||
800 | } | ||
801 | |||
802 | /* Adjust for changing gain */ | ||
803 | if( gain_adj_Q16 != (opus_int32)1 << 16 ) { | ||
804 | /* Scale long-term shaping state */ | ||
805 | { | ||
806 | __m128i xmm_gain_adj_Q16, xmm_sLTP_shp_Q14_x2x0, xmm_sLTP_shp_Q14_x3x1; | ||
807 | |||
808 | /* prepare gain_adj_Q16 in packed 4 32-bits */ | ||
809 | xmm_gain_adj_Q16 = _mm_set1_epi32( gain_adj_Q16 ); | ||
810 | |||
811 | for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx - 3; i += 4 ) | ||
812 | { | ||
813 | xmm_sLTP_shp_Q14_x2x0 = _mm_loadu_si128( (__m128i *)(&(NSQ->sLTP_shp_Q14[ i ] ) ) ); | ||
814 | /* equal shift right 4 bytes*/ | ||
815 | xmm_sLTP_shp_Q14_x3x1 = _mm_shuffle_epi32( xmm_sLTP_shp_Q14_x2x0, _MM_SHUFFLE( 0, 3, 2, 1 ) ); | ||
816 | |||
817 | xmm_sLTP_shp_Q14_x2x0 = _mm_mul_epi32( xmm_sLTP_shp_Q14_x2x0, xmm_gain_adj_Q16 ); | ||
818 | xmm_sLTP_shp_Q14_x3x1 = _mm_mul_epi32( xmm_sLTP_shp_Q14_x3x1, xmm_gain_adj_Q16 ); | ||
819 | |||
820 | xmm_sLTP_shp_Q14_x2x0 = _mm_srli_epi64( xmm_sLTP_shp_Q14_x2x0, 16 ); | ||
821 | xmm_sLTP_shp_Q14_x3x1 = _mm_slli_epi64( xmm_sLTP_shp_Q14_x3x1, 16 ); | ||
822 | |||
823 | xmm_sLTP_shp_Q14_x2x0 = _mm_blend_epi16( xmm_sLTP_shp_Q14_x2x0, xmm_sLTP_shp_Q14_x3x1, 0xCC ); | ||
824 | |||
825 | _mm_storeu_si128( (__m128i *)(&(NSQ->sLTP_shp_Q14[ i ] ) ), xmm_sLTP_shp_Q14_x2x0 ); | ||
826 | } | ||
827 | |||
828 | for( ; i < NSQ->sLTP_shp_buf_idx; i++ ) { | ||
829 | NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] ); | ||
830 | } | ||
831 | |||
832 | /* Scale long-term prediction state */ | ||
833 | if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) { | ||
834 | for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx - decisionDelay; i++ ) { | ||
835 | sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] ); | ||
836 | } | ||
837 | } | ||
838 | |||
839 | for( k = 0; k < nStatesDelayedDecision; k++ ) { | ||
840 | psDD = &psDelDec[ k ]; | ||
841 | |||
842 | /* Scale scalar states */ | ||
843 | psDD->LF_AR_Q14 = silk_SMULWW( gain_adj_Q16, psDD->LF_AR_Q14 ); | ||
844 | |||
845 | /* Scale short-term prediction and shaping states */ | ||
846 | for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) { | ||
847 | psDD->sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->sLPC_Q14[ i ] ); | ||
848 | } | ||
849 | for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) { | ||
850 | psDD->sAR2_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->sAR2_Q14[ i ] ); | ||
851 | } | ||
852 | for( i = 0; i < DECISION_DELAY; i++ ) { | ||
853 | psDD->Pred_Q15[ i ] = silk_SMULWW( gain_adj_Q16, psDD->Pred_Q15[ i ] ); | ||
854 | psDD->Shape_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->Shape_Q14[ i ] ); | ||
855 | } | ||
856 | } | ||
857 | } | ||
858 | } | ||
859 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/x86/NSQ_sse4_1.c b/lib/rbcodec/codecs/libopus/silk/x86/NSQ_sse4_1.c new file mode 100644 index 0000000000..b0315e35fc --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/x86/NSQ_sse4_1.c | |||
@@ -0,0 +1,719 @@ | |||
1 | /* Copyright (c) 2014, Cisco Systems, INC | ||
2 | Written by XiangMingZhu WeiZhou MinPeng YanWang | ||
3 | |||
4 | Redistribution and use in source and binary forms, with or without | ||
5 | modification, are permitted provided that the following conditions | ||
6 | are met: | ||
7 | |||
8 | - Redistributions of source code must retain the above copyright | ||
9 | notice, this list of conditions and the following disclaimer. | ||
10 | |||
11 | - Redistributions in binary form must reproduce the above copyright | ||
12 | notice, this list of conditions and the following disclaimer in the | ||
13 | documentation and/or other materials provided with the distribution. | ||
14 | |||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
16 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
17 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
18 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER | ||
19 | OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
20 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
21 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
22 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
23 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
24 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include <xmmintrin.h> | ||
33 | #include <emmintrin.h> | ||
34 | #include <smmintrin.h> | ||
35 | #include "main.h" | ||
36 | #include "celt/x86/x86cpu.h" | ||
37 | #include "stack_alloc.h" | ||
38 | |||
39 | static OPUS_INLINE void silk_nsq_scale_states_sse4_1( | ||
40 | const silk_encoder_state *psEncC, /* I Encoder State */ | ||
41 | silk_nsq_state *NSQ, /* I/O NSQ state */ | ||
42 | const opus_int32 x_Q3[], /* I input in Q3 */ | ||
43 | opus_int32 x_sc_Q10[], /* O input scaled with 1/Gain */ | ||
44 | const opus_int16 sLTP[], /* I re-whitened LTP state in Q0 */ | ||
45 | opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ | ||
46 | opus_int subfr, /* I subframe number */ | ||
47 | const opus_int LTP_scale_Q14, /* I */ | ||
48 | const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ | ||
49 | const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */ | ||
50 | const opus_int signal_type /* I Signal type */ | ||
51 | ); | ||
52 | |||
53 | static OPUS_INLINE void silk_noise_shape_quantizer_10_16_sse4_1( | ||
54 | silk_nsq_state *NSQ, /* I/O NSQ state */ | ||
55 | opus_int signalType, /* I Signal type */ | ||
56 | const opus_int32 x_sc_Q10[], /* I */ | ||
57 | opus_int8 pulses[], /* O */ | ||
58 | opus_int16 xq[], /* O */ | ||
59 | opus_int32 sLTP_Q15[], /* I/O LTP state */ | ||
60 | const opus_int16 a_Q12[], /* I Short term prediction coefs */ | ||
61 | const opus_int16 b_Q14[], /* I Long term prediction coefs */ | ||
62 | const opus_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */ | ||
63 | opus_int lag, /* I Pitch lag */ | ||
64 | opus_int32 HarmShapeFIRPacked_Q14, /* I */ | ||
65 | opus_int Tilt_Q14, /* I Spectral tilt */ | ||
66 | opus_int32 LF_shp_Q14, /* I */ | ||
67 | opus_int32 Gain_Q16, /* I */ | ||
68 | opus_int offset_Q10, /* I */ | ||
69 | opus_int length, /* I Input length */ | ||
70 | opus_int32 table[][4] /* I */ | ||
71 | ); | ||
72 | |||
73 | void silk_NSQ_sse4_1( | ||
74 | const silk_encoder_state *psEncC, /* I Encoder State */ | ||
75 | silk_nsq_state *NSQ, /* I/O NSQ state */ | ||
76 | SideInfoIndices *psIndices, /* I/O Quantization Indices */ | ||
77 | const opus_int32 x_Q3[], /* I Prefiltered input signal */ | ||
78 | opus_int8 pulses[], /* O Quantized pulse signal */ | ||
79 | const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ | ||
80 | const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ | ||
81 | const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ | ||
82 | const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ | ||
83 | const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ | ||
84 | const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ | ||
85 | const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ | ||
86 | const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ | ||
87 | const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ | ||
88 | const opus_int LTP_scale_Q14 /* I LTP state scaling */ | ||
89 | ) | ||
90 | { | ||
91 | opus_int k, lag, start_idx, LSF_interpolation_flag; | ||
92 | const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13; | ||
93 | opus_int16 *pxq; | ||
94 | VARDECL( opus_int32, sLTP_Q15 ); | ||
95 | VARDECL( opus_int16, sLTP ); | ||
96 | opus_int32 HarmShapeFIRPacked_Q14; | ||
97 | opus_int offset_Q10; | ||
98 | VARDECL( opus_int32, x_sc_Q10 ); | ||
99 | |||
100 | opus_int32 table[ 64 ][ 4 ]; | ||
101 | opus_int32 tmp1; | ||
102 | opus_int32 q1_Q10, q2_Q10, rd1_Q20, rd2_Q20; | ||
103 | |||
104 | SAVE_STACK; | ||
105 | |||
106 | NSQ->rand_seed = psIndices->Seed; | ||
107 | |||
108 | /* Set unvoiced lag to the previous one, overwrite later for voiced */ | ||
109 | lag = NSQ->lagPrev; | ||
110 | |||
111 | silk_assert( NSQ->prev_gain_Q16 != 0 ); | ||
112 | |||
113 | offset_Q10 = silk_Quantization_Offsets_Q10[ psIndices->signalType >> 1 ][ psIndices->quantOffsetType ]; | ||
114 | |||
115 | /* 0 */ | ||
116 | q1_Q10 = offset_Q10; | ||
117 | q2_Q10 = offset_Q10 + ( 1024 - QUANT_LEVEL_ADJUST_Q10 ); | ||
118 | rd1_Q20 = q1_Q10 * Lambda_Q10; | ||
119 | rd2_Q20 = q2_Q10 * Lambda_Q10; | ||
120 | |||
121 | table[ 32 ][ 0 ] = q1_Q10; | ||
122 | table[ 32 ][ 1 ] = q2_Q10; | ||
123 | table[ 32 ][ 2 ] = 2 * (q1_Q10 - q2_Q10); | ||
124 | table[ 32 ][ 3 ] = (rd1_Q20 - rd2_Q20) + (q1_Q10 * q1_Q10 - q2_Q10 * q2_Q10); | ||
125 | |||
126 | /* -1 */ | ||
127 | q1_Q10 = offset_Q10 - ( 1024 - QUANT_LEVEL_ADJUST_Q10 ); | ||
128 | q2_Q10 = offset_Q10; | ||
129 | rd1_Q20 = - q1_Q10 * Lambda_Q10; | ||
130 | rd2_Q20 = q2_Q10 * Lambda_Q10; | ||
131 | |||
132 | table[ 31 ][ 0 ] = q1_Q10; | ||
133 | table[ 31 ][ 1 ] = q2_Q10; | ||
134 | table[ 31 ][ 2 ] = 2 * (q1_Q10 - q2_Q10); | ||
135 | table[ 31 ][ 3 ] = (rd1_Q20 - rd2_Q20) + (q1_Q10 * q1_Q10 - q2_Q10 * q2_Q10); | ||
136 | |||
137 | /* > 0 */ | ||
138 | for (k = 1; k <= 31; k++) | ||
139 | { | ||
140 | tmp1 = offset_Q10 + silk_LSHIFT( k, 10 ); | ||
141 | |||
142 | q1_Q10 = tmp1 - QUANT_LEVEL_ADJUST_Q10; | ||
143 | q2_Q10 = tmp1 - QUANT_LEVEL_ADJUST_Q10 + 1024; | ||
144 | rd1_Q20 = q1_Q10 * Lambda_Q10; | ||
145 | rd2_Q20 = q2_Q10 * Lambda_Q10; | ||
146 | |||
147 | table[ 32 + k ][ 0 ] = q1_Q10; | ||
148 | table[ 32 + k ][ 1 ] = q2_Q10; | ||
149 | table[ 32 + k ][ 2 ] = 2 * (q1_Q10 - q2_Q10); | ||
150 | table[ 32 + k ][ 3 ] = (rd1_Q20 - rd2_Q20) + (q1_Q10 * q1_Q10 - q2_Q10 * q2_Q10); | ||
151 | } | ||
152 | |||
153 | /* < -1 */ | ||
154 | for (k = -32; k <= -2; k++) | ||
155 | { | ||
156 | tmp1 = offset_Q10 + silk_LSHIFT( k, 10 ); | ||
157 | |||
158 | q1_Q10 = tmp1 + QUANT_LEVEL_ADJUST_Q10; | ||
159 | q2_Q10 = tmp1 + QUANT_LEVEL_ADJUST_Q10 + 1024; | ||
160 | rd1_Q20 = - q1_Q10 * Lambda_Q10; | ||
161 | rd2_Q20 = - q2_Q10 * Lambda_Q10; | ||
162 | |||
163 | table[ 32 + k ][ 0 ] = q1_Q10; | ||
164 | table[ 32 + k ][ 1 ] = q2_Q10; | ||
165 | table[ 32 + k ][ 2 ] = 2 * (q1_Q10 - q2_Q10); | ||
166 | table[ 32 + k ][ 3 ] = (rd1_Q20 - rd2_Q20) + (q1_Q10 * q1_Q10 - q2_Q10 * q2_Q10); | ||
167 | } | ||
168 | |||
169 | if( psIndices->NLSFInterpCoef_Q2 == 4 ) { | ||
170 | LSF_interpolation_flag = 0; | ||
171 | } else { | ||
172 | LSF_interpolation_flag = 1; | ||
173 | } | ||
174 | |||
175 | ALLOC( sLTP_Q15, | ||
176 | psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 ); | ||
177 | ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 ); | ||
178 | ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 ); | ||
179 | /* Set up pointers to start of sub frame */ | ||
180 | NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length; | ||
181 | NSQ->sLTP_buf_idx = psEncC->ltp_mem_length; | ||
182 | pxq = &NSQ->xq[ psEncC->ltp_mem_length ]; | ||
183 | for( k = 0; k < psEncC->nb_subfr; k++ ) { | ||
184 | A_Q12 = &PredCoef_Q12[ (( k >> 1 ) | ( 1 - LSF_interpolation_flag )) * MAX_LPC_ORDER ]; | ||
185 | B_Q14 = <PCoef_Q14[ k * LTP_ORDER ]; | ||
186 | AR_shp_Q13 = &AR2_Q13[ k * MAX_SHAPE_LPC_ORDER ]; | ||
187 | |||
188 | /* Noise shape parameters */ | ||
189 | silk_assert( HarmShapeGain_Q14[ k ] >= 0 ); | ||
190 | HarmShapeFIRPacked_Q14 = silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 ); | ||
191 | HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 ); | ||
192 | |||
193 | NSQ->rewhite_flag = 0; | ||
194 | if( psIndices->signalType == TYPE_VOICED ) { | ||
195 | /* Voiced */ | ||
196 | lag = pitchL[ k ]; | ||
197 | |||
198 | /* Re-whitening */ | ||
199 | if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) { | ||
200 | /* Rewhiten with new A coefs */ | ||
201 | start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2; | ||
202 | celt_assert( start_idx > 0 ); | ||
203 | |||
204 | silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ], | ||
205 | A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder, psEncC->arch ); | ||
206 | |||
207 | NSQ->rewhite_flag = 1; | ||
208 | NSQ->sLTP_buf_idx = psEncC->ltp_mem_length; | ||
209 | } | ||
210 | } | ||
211 | |||
212 | silk_nsq_scale_states_sse4_1( psEncC, NSQ, x_Q3, x_sc_Q10, sLTP, sLTP_Q15, k, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType ); | ||
213 | |||
214 | if ( opus_likely( ( 10 == psEncC->shapingLPCOrder ) && ( 16 == psEncC->predictLPCOrder) ) ) | ||
215 | { | ||
216 | silk_noise_shape_quantizer_10_16_sse4_1( NSQ, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15, A_Q12, B_Q14, | ||
217 | AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ], | ||
218 | offset_Q10, psEncC->subfr_length, &(table[32]) ); | ||
219 | } | ||
220 | else | ||
221 | { | ||
222 | silk_noise_shape_quantizer( NSQ, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15, A_Q12, B_Q14, | ||
223 | AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ], Lambda_Q10, | ||
224 | offset_Q10, psEncC->subfr_length, psEncC->shapingLPCOrder, psEncC->predictLPCOrder, psEncC->arch ); | ||
225 | } | ||
226 | |||
227 | x_Q3 += psEncC->subfr_length; | ||
228 | pulses += psEncC->subfr_length; | ||
229 | pxq += psEncC->subfr_length; | ||
230 | } | ||
231 | |||
232 | /* Update lagPrev for next frame */ | ||
233 | NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ]; | ||
234 | |||
235 | /* Save quantized speech and noise shaping signals */ | ||
236 | silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) ); | ||
237 | silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) ); | ||
238 | RESTORE_STACK; | ||
239 | } | ||
240 | |||
241 | /***********************************/ | ||
242 | /* silk_noise_shape_quantizer_10_16 */ | ||
243 | /***********************************/ | ||
244 | static OPUS_INLINE void silk_noise_shape_quantizer_10_16_sse4_1( | ||
245 | silk_nsq_state *NSQ, /* I/O NSQ state */ | ||
246 | opus_int signalType, /* I Signal type */ | ||
247 | const opus_int32 x_sc_Q10[], /* I */ | ||
248 | opus_int8 pulses[], /* O */ | ||
249 | opus_int16 xq[], /* O */ | ||
250 | opus_int32 sLTP_Q15[], /* I/O LTP state */ | ||
251 | const opus_int16 a_Q12[], /* I Short term prediction coefs */ | ||
252 | const opus_int16 b_Q14[], /* I Long term prediction coefs */ | ||
253 | const opus_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */ | ||
254 | opus_int lag, /* I Pitch lag */ | ||
255 | opus_int32 HarmShapeFIRPacked_Q14, /* I */ | ||
256 | opus_int Tilt_Q14, /* I Spectral tilt */ | ||
257 | opus_int32 LF_shp_Q14, /* I */ | ||
258 | opus_int32 Gain_Q16, /* I */ | ||
259 | opus_int offset_Q10, /* I */ | ||
260 | opus_int length, /* I Input length */ | ||
261 | opus_int32 table[][4] /* I */ | ||
262 | ) | ||
263 | { | ||
264 | opus_int i; | ||
265 | opus_int32 LTP_pred_Q13, LPC_pred_Q10, n_AR_Q12, n_LTP_Q13; | ||
266 | opus_int32 n_LF_Q12, r_Q10, q1_Q0, q1_Q10, q2_Q10; | ||
267 | opus_int32 exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10; | ||
268 | opus_int32 tmp1, tmp2, sLF_AR_shp_Q14; | ||
269 | opus_int32 *psLPC_Q14, *shp_lag_ptr, *pred_lag_ptr; | ||
270 | |||
271 | __m128i xmm_tempa, xmm_tempb; | ||
272 | |||
273 | __m128i xmm_one; | ||
274 | |||
275 | __m128i psLPC_Q14_hi_01234567, psLPC_Q14_hi_89ABCDEF; | ||
276 | __m128i psLPC_Q14_lo_01234567, psLPC_Q14_lo_89ABCDEF; | ||
277 | __m128i a_Q12_01234567, a_Q12_89ABCDEF; | ||
278 | |||
279 | __m128i sAR2_Q14_hi_76543210, sAR2_Q14_lo_76543210; | ||
280 | __m128i AR_shp_Q13_76543210; | ||
281 | |||
282 | shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ]; | ||
283 | pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ]; | ||
284 | Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 ); | ||
285 | |||
286 | /* Set up short term AR state */ | ||
287 | psLPC_Q14 = &NSQ->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 ]; | ||
288 | |||
289 | sLF_AR_shp_Q14 = NSQ->sLF_AR_shp_Q14; | ||
290 | xq_Q14 = psLPC_Q14[ 0 ]; | ||
291 | LTP_pred_Q13 = 0; | ||
292 | |||
293 | /* load a_Q12 */ | ||
294 | xmm_one = _mm_set_epi8( 1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14 ); | ||
295 | |||
296 | /* load a_Q12[0] - a_Q12[7] */ | ||
297 | a_Q12_01234567 = _mm_loadu_si128( (__m128i *)(&a_Q12[ 0 ] ) ); | ||
298 | /* load a_Q12[ 8 ] - a_Q12[ 15 ] */ | ||
299 | a_Q12_89ABCDEF = _mm_loadu_si128( (__m128i *)(&a_Q12[ 8 ] ) ); | ||
300 | |||
301 | a_Q12_01234567 = _mm_shuffle_epi8( a_Q12_01234567, xmm_one ); | ||
302 | a_Q12_89ABCDEF = _mm_shuffle_epi8( a_Q12_89ABCDEF, xmm_one ); | ||
303 | |||
304 | /* load AR_shp_Q13 */ | ||
305 | AR_shp_Q13_76543210 = _mm_loadu_si128( (__m128i *)(&AR_shp_Q13[0] ) ); | ||
306 | |||
307 | /* load psLPC_Q14 */ | ||
308 | xmm_one = _mm_set_epi8(15, 14, 11, 10, 7, 6, 3, 2, 13, 12, 9, 8, 5, 4, 1, 0 ); | ||
309 | |||
310 | xmm_tempa = _mm_loadu_si128( (__m128i *)(&psLPC_Q14[-16]) ); | ||
311 | xmm_tempb = _mm_loadu_si128( (__m128i *)(&psLPC_Q14[-12]) ); | ||
312 | |||
313 | xmm_tempa = _mm_shuffle_epi8( xmm_tempa, xmm_one ); | ||
314 | xmm_tempb = _mm_shuffle_epi8( xmm_tempb, xmm_one ); | ||
315 | |||
316 | psLPC_Q14_hi_89ABCDEF = _mm_unpackhi_epi64( xmm_tempa, xmm_tempb ); | ||
317 | psLPC_Q14_lo_89ABCDEF = _mm_unpacklo_epi64( xmm_tempa, xmm_tempb ); | ||
318 | |||
319 | xmm_tempa = _mm_loadu_si128( (__m128i *)(&psLPC_Q14[ -8 ]) ); | ||
320 | xmm_tempb = _mm_loadu_si128( (__m128i *)(&psLPC_Q14[ -4 ]) ); | ||
321 | |||
322 | xmm_tempa = _mm_shuffle_epi8( xmm_tempa, xmm_one ); | ||
323 | xmm_tempb = _mm_shuffle_epi8( xmm_tempb, xmm_one ); | ||
324 | |||
325 | psLPC_Q14_hi_01234567 = _mm_unpackhi_epi64( xmm_tempa, xmm_tempb ); | ||
326 | psLPC_Q14_lo_01234567 = _mm_unpacklo_epi64( xmm_tempa, xmm_tempb ); | ||
327 | |||
328 | /* load sAR2_Q14 */ | ||
329 | xmm_tempa = _mm_loadu_si128( (__m128i *)(&(NSQ->sAR2_Q14[ 0 ]) ) ); | ||
330 | xmm_tempb = _mm_loadu_si128( (__m128i *)(&(NSQ->sAR2_Q14[ 4 ]) ) ); | ||
331 | |||
332 | xmm_tempa = _mm_shuffle_epi8( xmm_tempa, xmm_one ); | ||
333 | xmm_tempb = _mm_shuffle_epi8( xmm_tempb, xmm_one ); | ||
334 | |||
335 | sAR2_Q14_hi_76543210 = _mm_unpackhi_epi64( xmm_tempa, xmm_tempb ); | ||
336 | sAR2_Q14_lo_76543210 = _mm_unpacklo_epi64( xmm_tempa, xmm_tempb ); | ||
337 | |||
338 | /* prepare 1 in 8 * 16bit */ | ||
339 | xmm_one = _mm_set1_epi16(1); | ||
340 | |||
341 | for( i = 0; i < length; i++ ) | ||
342 | { | ||
343 | /* Short-term prediction */ | ||
344 | __m128i xmm_hi_07, xmm_hi_8F, xmm_lo_07, xmm_lo_8F; | ||
345 | |||
346 | /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ | ||
347 | LPC_pred_Q10 = 8; /* silk_RSHIFT( predictLPCOrder, 1 ); */ | ||
348 | |||
349 | /* shift psLPC_Q14 */ | ||
350 | psLPC_Q14_hi_89ABCDEF = _mm_alignr_epi8( psLPC_Q14_hi_01234567, psLPC_Q14_hi_89ABCDEF, 2 ); | ||
351 | psLPC_Q14_lo_89ABCDEF = _mm_alignr_epi8( psLPC_Q14_lo_01234567, psLPC_Q14_lo_89ABCDEF, 2 ); | ||
352 | |||
353 | psLPC_Q14_hi_01234567 = _mm_srli_si128( psLPC_Q14_hi_01234567, 2 ); | ||
354 | psLPC_Q14_lo_01234567 = _mm_srli_si128( psLPC_Q14_lo_01234567, 2 ); | ||
355 | |||
356 | psLPC_Q14_hi_01234567 = _mm_insert_epi16( psLPC_Q14_hi_01234567, (xq_Q14 >> 16), 7 ); | ||
357 | psLPC_Q14_lo_01234567 = _mm_insert_epi16( psLPC_Q14_lo_01234567, (xq_Q14), 7 ); | ||
358 | |||
359 | /* high part, use pmaddwd, results in 4 32-bit */ | ||
360 | xmm_hi_07 = _mm_madd_epi16( psLPC_Q14_hi_01234567, a_Q12_01234567 ); | ||
361 | xmm_hi_8F = _mm_madd_epi16( psLPC_Q14_hi_89ABCDEF, a_Q12_89ABCDEF ); | ||
362 | |||
363 | /* low part, use pmulhw, results in 8 16-bit, note we need simulate unsigned * signed, _mm_srai_epi16(psLPC_Q14_lo_01234567, 15) */ | ||
364 | xmm_tempa = _mm_cmpgt_epi16( _mm_setzero_si128(), psLPC_Q14_lo_01234567 ); | ||
365 | xmm_tempb = _mm_cmpgt_epi16( _mm_setzero_si128(), psLPC_Q14_lo_89ABCDEF ); | ||
366 | |||
367 | xmm_tempa = _mm_and_si128( xmm_tempa, a_Q12_01234567 ); | ||
368 | xmm_tempb = _mm_and_si128( xmm_tempb, a_Q12_89ABCDEF ); | ||
369 | |||
370 | xmm_lo_07 = _mm_mulhi_epi16( psLPC_Q14_lo_01234567, a_Q12_01234567 ); | ||
371 | xmm_lo_8F = _mm_mulhi_epi16( psLPC_Q14_lo_89ABCDEF, a_Q12_89ABCDEF ); | ||
372 | |||
373 | xmm_lo_07 = _mm_add_epi16( xmm_lo_07, xmm_tempa ); | ||
374 | xmm_lo_8F = _mm_add_epi16( xmm_lo_8F, xmm_tempb ); | ||
375 | |||
376 | xmm_lo_07 = _mm_madd_epi16( xmm_lo_07, xmm_one ); | ||
377 | xmm_lo_8F = _mm_madd_epi16( xmm_lo_8F, xmm_one ); | ||
378 | |||
379 | /* accumulate */ | ||
380 | xmm_hi_07 = _mm_add_epi32( xmm_hi_07, xmm_hi_8F ); | ||
381 | xmm_lo_07 = _mm_add_epi32( xmm_lo_07, xmm_lo_8F ); | ||
382 | |||
383 | xmm_hi_07 = _mm_add_epi32( xmm_hi_07, xmm_lo_07 ); | ||
384 | |||
385 | xmm_hi_07 = _mm_add_epi32( xmm_hi_07, _mm_unpackhi_epi64(xmm_hi_07, xmm_hi_07 ) ); | ||
386 | xmm_hi_07 = _mm_add_epi32( xmm_hi_07, _mm_shufflelo_epi16(xmm_hi_07, 0x0E ) ); | ||
387 | |||
388 | LPC_pred_Q10 += _mm_cvtsi128_si32( xmm_hi_07 ); | ||
389 | |||
390 | /* Long-term prediction */ | ||
391 | if ( opus_likely( signalType == TYPE_VOICED ) ) { | ||
392 | /* Unrolled loop */ | ||
393 | /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ | ||
394 | LTP_pred_Q13 = 2; | ||
395 | { | ||
396 | __m128i b_Q14_3210, b_Q14_0123, pred_lag_ptr_0123; | ||
397 | |||
398 | b_Q14_3210 = OP_CVTEPI16_EPI32_M64( b_Q14 ); | ||
399 | b_Q14_0123 = _mm_shuffle_epi32( b_Q14_3210, 0x1B ); | ||
400 | |||
401 | /* loaded: [0] [-1] [-2] [-3] */ | ||
402 | pred_lag_ptr_0123 = _mm_loadu_si128( (__m128i *)(&pred_lag_ptr[ -3 ] ) ); | ||
403 | /* shuffle to [-3] [-2] [-1] [0] and to new xmm */ | ||
404 | xmm_tempa = _mm_shuffle_epi32( pred_lag_ptr_0123, 0x1B ); | ||
405 | /*64-bit multiply, a[2] * b[-2], a[0] * b[0] */ | ||
406 | xmm_tempa = _mm_mul_epi32( xmm_tempa, b_Q14_3210 ); | ||
407 | /* right shift 2 bytes (16 bits), zero extended */ | ||
408 | xmm_tempa = _mm_srli_si128( xmm_tempa, 2 ); | ||
409 | |||
410 | /* a[1] * b[-1], a[3] * b[-3] */ | ||
411 | pred_lag_ptr_0123 = _mm_mul_epi32( pred_lag_ptr_0123, b_Q14_0123 ); | ||
412 | pred_lag_ptr_0123 = _mm_srli_si128( pred_lag_ptr_0123, 2 ); | ||
413 | |||
414 | pred_lag_ptr_0123 = _mm_add_epi32( pred_lag_ptr_0123, xmm_tempa ); | ||
415 | /* equal shift right 8 bytes*/ | ||
416 | xmm_tempa = _mm_shuffle_epi32( pred_lag_ptr_0123, _MM_SHUFFLE( 0, 0, 3, 2 ) ); | ||
417 | xmm_tempa = _mm_add_epi32( xmm_tempa, pred_lag_ptr_0123 ); | ||
418 | |||
419 | LTP_pred_Q13 += _mm_cvtsi128_si32( xmm_tempa ); | ||
420 | |||
421 | LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -4 ], b_Q14[ 4 ] ); | ||
422 | pred_lag_ptr++; | ||
423 | } | ||
424 | } | ||
425 | |||
426 | /* Noise shape feedback */ | ||
427 | NSQ->sAR2_Q14[ 9 ] = NSQ->sAR2_Q14[ 8 ]; | ||
428 | NSQ->sAR2_Q14[ 8 ] = _mm_cvtsi128_si32( _mm_srli_si128(_mm_unpackhi_epi16( sAR2_Q14_lo_76543210, sAR2_Q14_hi_76543210 ), 12 ) ); | ||
429 | |||
430 | sAR2_Q14_hi_76543210 = _mm_slli_si128( sAR2_Q14_hi_76543210, 2 ); | ||
431 | sAR2_Q14_lo_76543210 = _mm_slli_si128( sAR2_Q14_lo_76543210, 2 ); | ||
432 | |||
433 | sAR2_Q14_hi_76543210 = _mm_insert_epi16( sAR2_Q14_hi_76543210, (xq_Q14 >> 16), 0 ); | ||
434 | sAR2_Q14_lo_76543210 = _mm_insert_epi16( sAR2_Q14_lo_76543210, (xq_Q14), 0 ); | ||
435 | |||
436 | /* high part, use pmaddwd, results in 4 32-bit */ | ||
437 | xmm_hi_07 = _mm_madd_epi16( sAR2_Q14_hi_76543210, AR_shp_Q13_76543210 ); | ||
438 | |||
439 | /* low part, use pmulhw, results in 8 16-bit, note we need simulate unsigned * signed,_mm_srai_epi16(sAR2_Q14_lo_76543210, 15) */ | ||
440 | xmm_tempa = _mm_cmpgt_epi16( _mm_setzero_si128(), sAR2_Q14_lo_76543210 ); | ||
441 | xmm_tempa = _mm_and_si128( xmm_tempa, AR_shp_Q13_76543210 ); | ||
442 | |||
443 | xmm_lo_07 = _mm_mulhi_epi16( sAR2_Q14_lo_76543210, AR_shp_Q13_76543210 ); | ||
444 | xmm_lo_07 = _mm_add_epi16( xmm_lo_07, xmm_tempa ); | ||
445 | |||
446 | xmm_lo_07 = _mm_madd_epi16( xmm_lo_07, xmm_one ); | ||
447 | |||
448 | /* accumulate */ | ||
449 | xmm_hi_07 = _mm_add_epi32( xmm_hi_07, xmm_lo_07 ); | ||
450 | |||
451 | xmm_hi_07 = _mm_add_epi32( xmm_hi_07, _mm_unpackhi_epi64(xmm_hi_07, xmm_hi_07 ) ); | ||
452 | xmm_hi_07 = _mm_add_epi32( xmm_hi_07, _mm_shufflelo_epi16(xmm_hi_07, 0x0E ) ); | ||
453 | |||
454 | n_AR_Q12 = 5 + _mm_cvtsi128_si32( xmm_hi_07 ); | ||
455 | |||
456 | n_AR_Q12 = silk_SMLAWB( n_AR_Q12, NSQ->sAR2_Q14[ 8 ], AR_shp_Q13[ 8 ] ); | ||
457 | n_AR_Q12 = silk_SMLAWB( n_AR_Q12, NSQ->sAR2_Q14[ 9 ], AR_shp_Q13[ 9 ] ); | ||
458 | |||
459 | n_AR_Q12 = silk_LSHIFT32( n_AR_Q12, 1 ); /* Q11 -> Q12 */ | ||
460 | n_AR_Q12 = silk_SMLAWB( n_AR_Q12, sLF_AR_shp_Q14, Tilt_Q14 ); | ||
461 | |||
462 | n_LF_Q12 = silk_SMULWB( NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - 1 ], LF_shp_Q14 ); | ||
463 | n_LF_Q12 = silk_SMLAWT( n_LF_Q12, sLF_AR_shp_Q14, LF_shp_Q14 ); | ||
464 | |||
465 | silk_assert( lag > 0 || signalType != TYPE_VOICED ); | ||
466 | |||
467 | /* Combine prediction and noise shaping signals */ | ||
468 | tmp1 = silk_SUB32( silk_LSHIFT32( LPC_pred_Q10, 2 ), n_AR_Q12 ); /* Q12 */ | ||
469 | tmp1 = silk_SUB32( tmp1, n_LF_Q12 ); /* Q12 */ | ||
470 | if( lag > 0 ) { | ||
471 | /* Symmetric, packed FIR coefficients */ | ||
472 | n_LTP_Q13 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 ); | ||
473 | n_LTP_Q13 = silk_SMLAWT( n_LTP_Q13, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 ); | ||
474 | n_LTP_Q13 = silk_LSHIFT( n_LTP_Q13, 1 ); | ||
475 | shp_lag_ptr++; | ||
476 | |||
477 | tmp2 = silk_SUB32( LTP_pred_Q13, n_LTP_Q13 ); /* Q13 */ | ||
478 | tmp1 = silk_ADD_LSHIFT32( tmp2, tmp1, 1 ); /* Q13 */ | ||
479 | tmp1 = silk_RSHIFT_ROUND( tmp1, 3 ); /* Q10 */ | ||
480 | } else { | ||
481 | tmp1 = silk_RSHIFT_ROUND( tmp1, 2 ); /* Q10 */ | ||
482 | } | ||
483 | |||
484 | r_Q10 = silk_SUB32( x_sc_Q10[ i ], tmp1 ); /* residual error Q10 */ | ||
485 | |||
486 | /* Generate dither */ | ||
487 | NSQ->rand_seed = silk_RAND( NSQ->rand_seed ); | ||
488 | |||
489 | /* Flip sign depending on dither */ | ||
490 | tmp2 = -r_Q10; | ||
491 | if ( NSQ->rand_seed < 0 ) r_Q10 = tmp2; | ||
492 | |||
493 | r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 ); | ||
494 | |||
495 | /* Find two quantization level candidates and measure their rate-distortion */ | ||
496 | q1_Q10 = silk_SUB32( r_Q10, offset_Q10 ); | ||
497 | q1_Q0 = silk_RSHIFT( q1_Q10, 10 ); | ||
498 | |||
499 | q1_Q10 = table[q1_Q0][0]; | ||
500 | q2_Q10 = table[q1_Q0][1]; | ||
501 | |||
502 | if (r_Q10 * table[q1_Q0][2] - table[q1_Q0][3] < 0) | ||
503 | { | ||
504 | q1_Q10 = q2_Q10; | ||
505 | } | ||
506 | |||
507 | pulses[ i ] = (opus_int8)silk_RSHIFT_ROUND( q1_Q10, 10 ); | ||
508 | |||
509 | /* Excitation */ | ||
510 | exc_Q14 = silk_LSHIFT( q1_Q10, 4 ); | ||
511 | |||
512 | tmp2 = -exc_Q14; | ||
513 | if ( NSQ->rand_seed < 0 ) exc_Q14 = tmp2; | ||
514 | |||
515 | /* Add predictions */ | ||
516 | LPC_exc_Q14 = silk_ADD_LSHIFT32( exc_Q14, LTP_pred_Q13, 1 ); | ||
517 | xq_Q14 = silk_ADD_LSHIFT32( LPC_exc_Q14, LPC_pred_Q10, 4 ); | ||
518 | |||
519 | /* Update states */ | ||
520 | psLPC_Q14++; | ||
521 | *psLPC_Q14 = xq_Q14; | ||
522 | sLF_AR_shp_Q14 = silk_SUB_LSHIFT32( xq_Q14, n_AR_Q12, 2 ); | ||
523 | |||
524 | NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx ] = silk_SUB_LSHIFT32( sLF_AR_shp_Q14, n_LF_Q12, 2 ); | ||
525 | sLTP_Q15[ NSQ->sLTP_buf_idx ] = silk_LSHIFT( LPC_exc_Q14, 1 ); | ||
526 | NSQ->sLTP_shp_buf_idx++; | ||
527 | NSQ->sLTP_buf_idx++; | ||
528 | |||
529 | /* Make dither dependent on quantized signal */ | ||
530 | NSQ->rand_seed = silk_ADD32_ovflw( NSQ->rand_seed, pulses[ i ] ); | ||
531 | } | ||
532 | |||
533 | NSQ->sLF_AR_shp_Q14 = sLF_AR_shp_Q14; | ||
534 | |||
535 | /* Scale XQ back to normal level before saving */ | ||
536 | psLPC_Q14 = &NSQ->sLPC_Q14[ NSQ_LPC_BUF_LENGTH ]; | ||
537 | |||
538 | /* write back sAR2_Q14 */ | ||
539 | xmm_tempa = _mm_unpackhi_epi16( sAR2_Q14_lo_76543210, sAR2_Q14_hi_76543210 ); | ||
540 | xmm_tempb = _mm_unpacklo_epi16( sAR2_Q14_lo_76543210, sAR2_Q14_hi_76543210 ); | ||
541 | _mm_storeu_si128( (__m128i *)(&NSQ->sAR2_Q14[ 4 ]), xmm_tempa ); | ||
542 | _mm_storeu_si128( (__m128i *)(&NSQ->sAR2_Q14[ 0 ]), xmm_tempb ); | ||
543 | |||
544 | /* xq[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( psLPC_Q14[ i ], Gain_Q10 ), 8 ) ); */ | ||
545 | { | ||
546 | __m128i xmm_Gain_Q10; | ||
547 | __m128i xmm_xq_Q14_3210, xmm_xq_Q14_x3x1, xmm_xq_Q14_7654, xmm_xq_Q14_x7x5; | ||
548 | |||
549 | /* prepare (1 << 7) in packed 4 32-bits */ | ||
550 | xmm_tempa = _mm_set1_epi32( (1 << 7) ); | ||
551 | |||
552 | /* prepare Gain_Q10 in packed 4 32-bits */ | ||
553 | xmm_Gain_Q10 = _mm_set1_epi32( Gain_Q10 ); | ||
554 | |||
555 | /* process xq */ | ||
556 | for (i = 0; i < length - 7; i += 8) | ||
557 | { | ||
558 | xmm_xq_Q14_3210 = _mm_loadu_si128( (__m128i *)(&(psLPC_Q14[ i + 0 ] ) ) ); | ||
559 | xmm_xq_Q14_7654 = _mm_loadu_si128( (__m128i *)(&(psLPC_Q14[ i + 4 ] ) ) ); | ||
560 | |||
561 | /* equal shift right 4 bytes*/ | ||
562 | xmm_xq_Q14_x3x1 = _mm_shuffle_epi32( xmm_xq_Q14_3210, _MM_SHUFFLE( 0, 3, 2, 1 ) ); | ||
563 | /* equal shift right 4 bytes*/ | ||
564 | xmm_xq_Q14_x7x5 = _mm_shuffle_epi32( xmm_xq_Q14_7654, _MM_SHUFFLE( 0, 3, 2, 1 ) ); | ||
565 | |||
566 | xmm_xq_Q14_3210 = _mm_mul_epi32( xmm_xq_Q14_3210, xmm_Gain_Q10 ); | ||
567 | xmm_xq_Q14_x3x1 = _mm_mul_epi32( xmm_xq_Q14_x3x1, xmm_Gain_Q10 ); | ||
568 | xmm_xq_Q14_7654 = _mm_mul_epi32( xmm_xq_Q14_7654, xmm_Gain_Q10 ); | ||
569 | xmm_xq_Q14_x7x5 = _mm_mul_epi32( xmm_xq_Q14_x7x5, xmm_Gain_Q10 ); | ||
570 | |||
571 | xmm_xq_Q14_3210 = _mm_srli_epi64( xmm_xq_Q14_3210, 16 ); | ||
572 | xmm_xq_Q14_x3x1 = _mm_slli_epi64( xmm_xq_Q14_x3x1, 16 ); | ||
573 | xmm_xq_Q14_7654 = _mm_srli_epi64( xmm_xq_Q14_7654, 16 ); | ||
574 | xmm_xq_Q14_x7x5 = _mm_slli_epi64( xmm_xq_Q14_x7x5, 16 ); | ||
575 | |||
576 | xmm_xq_Q14_3210 = _mm_blend_epi16( xmm_xq_Q14_3210, xmm_xq_Q14_x3x1, 0xCC ); | ||
577 | xmm_xq_Q14_7654 = _mm_blend_epi16( xmm_xq_Q14_7654, xmm_xq_Q14_x7x5, 0xCC ); | ||
578 | |||
579 | /* silk_RSHIFT_ROUND(xq, 8) */ | ||
580 | xmm_xq_Q14_3210 = _mm_add_epi32( xmm_xq_Q14_3210, xmm_tempa ); | ||
581 | xmm_xq_Q14_7654 = _mm_add_epi32( xmm_xq_Q14_7654, xmm_tempa ); | ||
582 | |||
583 | xmm_xq_Q14_3210 = _mm_srai_epi32( xmm_xq_Q14_3210, 8 ); | ||
584 | xmm_xq_Q14_7654 = _mm_srai_epi32( xmm_xq_Q14_7654, 8 ); | ||
585 | |||
586 | /* silk_SAT16 */ | ||
587 | xmm_xq_Q14_3210 = _mm_packs_epi32( xmm_xq_Q14_3210, xmm_xq_Q14_7654 ); | ||
588 | |||
589 | /* save to xq */ | ||
590 | _mm_storeu_si128( (__m128i *)(&xq[ i ] ), xmm_xq_Q14_3210 ); | ||
591 | } | ||
592 | } | ||
593 | for ( ; i < length; i++) | ||
594 | { | ||
595 | xq[i] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( psLPC_Q14[ i ], Gain_Q10 ), 8 ) ); | ||
596 | } | ||
597 | |||
598 | /* Update LPC synth buffer */ | ||
599 | silk_memcpy( NSQ->sLPC_Q14, &NSQ->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) ); | ||
600 | } | ||
601 | |||
602 | static OPUS_INLINE void silk_nsq_scale_states_sse4_1( | ||
603 | const silk_encoder_state *psEncC, /* I Encoder State */ | ||
604 | silk_nsq_state *NSQ, /* I/O NSQ state */ | ||
605 | const opus_int32 x_Q3[], /* I input in Q3 */ | ||
606 | opus_int32 x_sc_Q10[], /* O input scaled with 1/Gain */ | ||
607 | const opus_int16 sLTP[], /* I re-whitened LTP state in Q0 */ | ||
608 | opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ | ||
609 | opus_int subfr, /* I subframe number */ | ||
610 | const opus_int LTP_scale_Q14, /* I */ | ||
611 | const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ | ||
612 | const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */ | ||
613 | const opus_int signal_type /* I Signal type */ | ||
614 | ) | ||
615 | { | ||
616 | opus_int i, lag; | ||
617 | opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q23; | ||
618 | __m128i xmm_inv_gain_Q23, xmm_x_Q3_x2x0, xmm_x_Q3_x3x1; | ||
619 | |||
620 | lag = pitchL[ subfr ]; | ||
621 | inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 ); | ||
622 | silk_assert( inv_gain_Q31 != 0 ); | ||
623 | |||
624 | /* Calculate gain adjustment factor */ | ||
625 | if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) { | ||
626 | gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 ); | ||
627 | } else { | ||
628 | gain_adj_Q16 = (opus_int32)1 << 16; | ||
629 | } | ||
630 | |||
631 | /* Scale input */ | ||
632 | inv_gain_Q23 = silk_RSHIFT_ROUND( inv_gain_Q31, 8 ); | ||
633 | |||
634 | /* prepare inv_gain_Q23 in packed 4 32-bits */ | ||
635 | xmm_inv_gain_Q23 = _mm_set1_epi32(inv_gain_Q23); | ||
636 | |||
637 | for( i = 0; i < psEncC->subfr_length - 3; i += 4 ) { | ||
638 | xmm_x_Q3_x2x0 = _mm_loadu_si128( (__m128i *)(&(x_Q3[ i ] ) ) ); | ||
639 | |||
640 | /* equal shift right 4 bytes*/ | ||
641 | xmm_x_Q3_x3x1 = _mm_shuffle_epi32( xmm_x_Q3_x2x0, _MM_SHUFFLE( 0, 3, 2, 1 ) ); | ||
642 | |||
643 | xmm_x_Q3_x2x0 = _mm_mul_epi32( xmm_x_Q3_x2x0, xmm_inv_gain_Q23 ); | ||
644 | xmm_x_Q3_x3x1 = _mm_mul_epi32( xmm_x_Q3_x3x1, xmm_inv_gain_Q23 ); | ||
645 | |||
646 | xmm_x_Q3_x2x0 = _mm_srli_epi64( xmm_x_Q3_x2x0, 16 ); | ||
647 | xmm_x_Q3_x3x1 = _mm_slli_epi64( xmm_x_Q3_x3x1, 16 ); | ||
648 | |||
649 | xmm_x_Q3_x2x0 = _mm_blend_epi16( xmm_x_Q3_x2x0, xmm_x_Q3_x3x1, 0xCC ); | ||
650 | |||
651 | _mm_storeu_si128( (__m128i *)(&(x_sc_Q10[ i ] ) ), xmm_x_Q3_x2x0 ); | ||
652 | } | ||
653 | |||
654 | for( ; i < psEncC->subfr_length; i++ ) { | ||
655 | x_sc_Q10[ i ] = silk_SMULWW( x_Q3[ i ], inv_gain_Q23 ); | ||
656 | } | ||
657 | |||
658 | /* Save inverse gain */ | ||
659 | NSQ->prev_gain_Q16 = Gains_Q16[ subfr ]; | ||
660 | |||
661 | /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */ | ||
662 | if( NSQ->rewhite_flag ) { | ||
663 | if( subfr == 0 ) { | ||
664 | /* Do LTP downscaling */ | ||
665 | inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 ); | ||
666 | } | ||
667 | for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) { | ||
668 | silk_assert( i < MAX_FRAME_LENGTH ); | ||
669 | sLTP_Q15[ i ] = silk_SMULWB( inv_gain_Q31, sLTP[ i ] ); | ||
670 | } | ||
671 | } | ||
672 | |||
673 | /* Adjust for changing gain */ | ||
674 | if( gain_adj_Q16 != (opus_int32)1 << 16 ) { | ||
675 | /* Scale long-term shaping state */ | ||
676 | __m128i xmm_gain_adj_Q16, xmm_sLTP_shp_Q14_x2x0, xmm_sLTP_shp_Q14_x3x1; | ||
677 | |||
678 | /* prepare gain_adj_Q16 in packed 4 32-bits */ | ||
679 | xmm_gain_adj_Q16 = _mm_set1_epi32(gain_adj_Q16); | ||
680 | |||
681 | for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx - 3; i += 4 ) | ||
682 | { | ||
683 | xmm_sLTP_shp_Q14_x2x0 = _mm_loadu_si128( (__m128i *)(&(NSQ->sLTP_shp_Q14[ i ] ) ) ); | ||
684 | /* equal shift right 4 bytes*/ | ||
685 | xmm_sLTP_shp_Q14_x3x1 = _mm_shuffle_epi32( xmm_sLTP_shp_Q14_x2x0, _MM_SHUFFLE( 0, 3, 2, 1 ) ); | ||
686 | |||
687 | xmm_sLTP_shp_Q14_x2x0 = _mm_mul_epi32( xmm_sLTP_shp_Q14_x2x0, xmm_gain_adj_Q16 ); | ||
688 | xmm_sLTP_shp_Q14_x3x1 = _mm_mul_epi32( xmm_sLTP_shp_Q14_x3x1, xmm_gain_adj_Q16 ); | ||
689 | |||
690 | xmm_sLTP_shp_Q14_x2x0 = _mm_srli_epi64( xmm_sLTP_shp_Q14_x2x0, 16 ); | ||
691 | xmm_sLTP_shp_Q14_x3x1 = _mm_slli_epi64( xmm_sLTP_shp_Q14_x3x1, 16 ); | ||
692 | |||
693 | xmm_sLTP_shp_Q14_x2x0 = _mm_blend_epi16( xmm_sLTP_shp_Q14_x2x0, xmm_sLTP_shp_Q14_x3x1, 0xCC ); | ||
694 | |||
695 | _mm_storeu_si128( (__m128i *)(&(NSQ->sLTP_shp_Q14[ i ] ) ), xmm_sLTP_shp_Q14_x2x0 ); | ||
696 | } | ||
697 | |||
698 | for( ; i < NSQ->sLTP_shp_buf_idx; i++ ) { | ||
699 | NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] ); | ||
700 | } | ||
701 | |||
702 | /* Scale long-term prediction state */ | ||
703 | if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) { | ||
704 | for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) { | ||
705 | sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] ); | ||
706 | } | ||
707 | } | ||
708 | |||
709 | NSQ->sLF_AR_shp_Q14 = silk_SMULWW( gain_adj_Q16, NSQ->sLF_AR_shp_Q14 ); | ||
710 | |||
711 | /* Scale short-term prediction and shaping states */ | ||
712 | for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) { | ||
713 | NSQ->sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLPC_Q14[ i ] ); | ||
714 | } | ||
715 | for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) { | ||
716 | NSQ->sAR2_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sAR2_Q14[ i ] ); | ||
717 | } | ||
718 | } | ||
719 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/x86/SigProc_FIX_sse.h b/lib/rbcodec/codecs/libopus/silk/x86/SigProc_FIX_sse.h new file mode 100644 index 0000000000..61efa8da41 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/x86/SigProc_FIX_sse.h | |||
@@ -0,0 +1,94 @@ | |||
1 | /* Copyright (c) 2014, Cisco Systems, INC | ||
2 | Written by XiangMingZhu WeiZhou MinPeng YanWang | ||
3 | |||
4 | Redistribution and use in source and binary forms, with or without | ||
5 | modification, are permitted provided that the following conditions | ||
6 | are met: | ||
7 | |||
8 | - Redistributions of source code must retain the above copyright | ||
9 | notice, this list of conditions and the following disclaimer. | ||
10 | |||
11 | - Redistributions in binary form must reproduce the above copyright | ||
12 | notice, this list of conditions and the following disclaimer in the | ||
13 | documentation and/or other materials provided with the distribution. | ||
14 | |||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
16 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
17 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
18 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER | ||
19 | OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
20 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
21 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
22 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
23 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
24 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | #ifndef SIGPROC_FIX_SSE_H | ||
29 | #define SIGPROC_FIX_SSE_H | ||
30 | |||
31 | #ifdef HAVE_CONFIG_H | ||
32 | #include "config.h" | ||
33 | #endif | ||
34 | |||
35 | #if defined(OPUS_X86_MAY_HAVE_SSE4_1) | ||
36 | void silk_burg_modified_sse4_1( | ||
37 | opus_int32 *res_nrg, /* O Residual energy */ | ||
38 | opus_int *res_nrg_Q, /* O Residual energy Q value */ | ||
39 | opus_int32 A_Q16[], /* O Prediction coefficients (length order) */ | ||
40 | const opus_int16 x[], /* I Input signal, length: nb_subfr * ( D + subfr_length ) */ | ||
41 | const opus_int32 minInvGain_Q30, /* I Inverse of max prediction gain */ | ||
42 | const opus_int subfr_length, /* I Input signal subframe length (incl. D preceding samples) */ | ||
43 | const opus_int nb_subfr, /* I Number of subframes stacked in x */ | ||
44 | const opus_int D, /* I Order */ | ||
45 | int arch /* I Run-time architecture */ | ||
46 | ); | ||
47 | |||
48 | #if defined(OPUS_X86_PRESUME_SSE4_1) | ||
49 | #define silk_burg_modified(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch) \ | ||
50 | ((void)(arch), silk_burg_modified_sse4_1(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch)) | ||
51 | |||
52 | #else | ||
53 | |||
54 | extern void (*const SILK_BURG_MODIFIED_IMPL[OPUS_ARCHMASK + 1])( | ||
55 | opus_int32 *res_nrg, /* O Residual energy */ | ||
56 | opus_int *res_nrg_Q, /* O Residual energy Q value */ | ||
57 | opus_int32 A_Q16[], /* O Prediction coefficients (length order) */ | ||
58 | const opus_int16 x[], /* I Input signal, length: nb_subfr * ( D + subfr_length ) */ | ||
59 | const opus_int32 minInvGain_Q30, /* I Inverse of max prediction gain */ | ||
60 | const opus_int subfr_length, /* I Input signal subframe length (incl. D preceding samples) */ | ||
61 | const opus_int nb_subfr, /* I Number of subframes stacked in x */ | ||
62 | const opus_int D, /* I Order */ | ||
63 | int arch /* I Run-time architecture */); | ||
64 | |||
65 | # define silk_burg_modified(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch) \ | ||
66 | ((*SILK_BURG_MODIFIED_IMPL[(arch) & OPUS_ARCHMASK])(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch)) | ||
67 | |||
68 | #endif | ||
69 | |||
70 | opus_int64 silk_inner_prod16_aligned_64_sse4_1( | ||
71 | const opus_int16 *inVec1, | ||
72 | const opus_int16 *inVec2, | ||
73 | const opus_int len | ||
74 | ); | ||
75 | |||
76 | |||
77 | #if defined(OPUS_X86_PRESUME_SSE4_1) | ||
78 | |||
79 | #define silk_inner_prod16_aligned_64(inVec1, inVec2, len, arch) \ | ||
80 | ((void)(arch),silk_inner_prod16_aligned_64_sse4_1(inVec1, inVec2, len)) | ||
81 | |||
82 | #else | ||
83 | |||
84 | extern opus_int64 (*const SILK_INNER_PROD16_ALIGNED_64_IMPL[OPUS_ARCHMASK + 1])( | ||
85 | const opus_int16 *inVec1, | ||
86 | const opus_int16 *inVec2, | ||
87 | const opus_int len); | ||
88 | |||
89 | # define silk_inner_prod16_aligned_64(inVec1, inVec2, len, arch) \ | ||
90 | ((*SILK_INNER_PROD16_ALIGNED_64_IMPL[(arch) & OPUS_ARCHMASK])(inVec1, inVec2, len)) | ||
91 | |||
92 | #endif | ||
93 | #endif | ||
94 | #endif | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/x86/VAD_sse4_1.c b/lib/rbcodec/codecs/libopus/silk/x86/VAD_sse4_1.c new file mode 100644 index 0000000000..d02ddf4ad0 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/x86/VAD_sse4_1.c | |||
@@ -0,0 +1,277 @@ | |||
1 | /* Copyright (c) 2014, Cisco Systems, INC | ||
2 | Written by XiangMingZhu WeiZhou MinPeng YanWang | ||
3 | |||
4 | Redistribution and use in source and binary forms, with or without | ||
5 | modification, are permitted provided that the following conditions | ||
6 | are met: | ||
7 | |||
8 | - Redistributions of source code must retain the above copyright | ||
9 | notice, this list of conditions and the following disclaimer. | ||
10 | |||
11 | - Redistributions in binary form must reproduce the above copyright | ||
12 | notice, this list of conditions and the following disclaimer in the | ||
13 | documentation and/or other materials provided with the distribution. | ||
14 | |||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
16 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
17 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
18 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER | ||
19 | OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
20 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
21 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
22 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
23 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
24 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include <xmmintrin.h> | ||
33 | #include <emmintrin.h> | ||
34 | #include <smmintrin.h> | ||
35 | |||
36 | #include "main.h" | ||
37 | #include "stack_alloc.h" | ||
38 | |||
39 | /* Weighting factors for tilt measure */ | ||
40 | static const opus_int32 tiltWeights[ VAD_N_BANDS ] = { 30000, 6000, -12000, -12000 }; | ||
41 | |||
42 | /***************************************/ | ||
43 | /* Get the speech activity level in Q8 */ | ||
44 | /***************************************/ | ||
45 | opus_int silk_VAD_GetSA_Q8_sse4_1( /* O Return value, 0 if success */ | ||
46 | silk_encoder_state *psEncC, /* I/O Encoder state */ | ||
47 | const opus_int16 pIn[] /* I PCM input */ | ||
48 | ) | ||
49 | { | ||
50 | opus_int SA_Q15, pSNR_dB_Q7, input_tilt; | ||
51 | opus_int decimated_framelength1, decimated_framelength2; | ||
52 | opus_int decimated_framelength; | ||
53 | opus_int dec_subframe_length, dec_subframe_offset, SNR_Q7, i, b, s; | ||
54 | opus_int32 sumSquared, smooth_coef_Q16; | ||
55 | opus_int16 HPstateTmp; | ||
56 | VARDECL( opus_int16, X ); | ||
57 | opus_int32 Xnrg[ VAD_N_BANDS ]; | ||
58 | opus_int32 NrgToNoiseRatio_Q8[ VAD_N_BANDS ]; | ||
59 | opus_int32 speech_nrg, x_tmp; | ||
60 | opus_int X_offset[ VAD_N_BANDS ]; | ||
61 | opus_int ret = 0; | ||
62 | silk_VAD_state *psSilk_VAD = &psEncC->sVAD; | ||
63 | |||
64 | SAVE_STACK; | ||
65 | |||
66 | /* Safety checks */ | ||
67 | silk_assert( VAD_N_BANDS == 4 ); | ||
68 | celt_assert( MAX_FRAME_LENGTH >= psEncC->frame_length ); | ||
69 | celt_assert( psEncC->frame_length <= 512 ); | ||
70 | celt_assert( psEncC->frame_length == 8 * silk_RSHIFT( psEncC->frame_length, 3 ) ); | ||
71 | |||
72 | /***********************/ | ||
73 | /* Filter and Decimate */ | ||
74 | /***********************/ | ||
75 | decimated_framelength1 = silk_RSHIFT( psEncC->frame_length, 1 ); | ||
76 | decimated_framelength2 = silk_RSHIFT( psEncC->frame_length, 2 ); | ||
77 | decimated_framelength = silk_RSHIFT( psEncC->frame_length, 3 ); | ||
78 | /* Decimate into 4 bands: | ||
79 | 0 L 3L L 3L 5L | ||
80 | - -- - -- -- | ||
81 | 8 8 2 4 4 | ||
82 | |||
83 | [0-1 kHz| temp. |1-2 kHz| 2-4 kHz | 4-8 kHz | | ||
84 | |||
85 | They're arranged to allow the minimal ( frame_length / 4 ) extra | ||
86 | scratch space during the downsampling process */ | ||
87 | X_offset[ 0 ] = 0; | ||
88 | X_offset[ 1 ] = decimated_framelength + decimated_framelength2; | ||
89 | X_offset[ 2 ] = X_offset[ 1 ] + decimated_framelength; | ||
90 | X_offset[ 3 ] = X_offset[ 2 ] + decimated_framelength2; | ||
91 | ALLOC( X, X_offset[ 3 ] + decimated_framelength1, opus_int16 ); | ||
92 | |||
93 | /* 0-8 kHz to 0-4 kHz and 4-8 kHz */ | ||
94 | silk_ana_filt_bank_1( pIn, &psSilk_VAD->AnaState[ 0 ], | ||
95 | X, &X[ X_offset[ 3 ] ], psEncC->frame_length ); | ||
96 | |||
97 | /* 0-4 kHz to 0-2 kHz and 2-4 kHz */ | ||
98 | silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState1[ 0 ], | ||
99 | X, &X[ X_offset[ 2 ] ], decimated_framelength1 ); | ||
100 | |||
101 | /* 0-2 kHz to 0-1 kHz and 1-2 kHz */ | ||
102 | silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState2[ 0 ], | ||
103 | X, &X[ X_offset[ 1 ] ], decimated_framelength2 ); | ||
104 | |||
105 | /*********************************************/ | ||
106 | /* HP filter on lowest band (differentiator) */ | ||
107 | /*********************************************/ | ||
108 | X[ decimated_framelength - 1 ] = silk_RSHIFT( X[ decimated_framelength - 1 ], 1 ); | ||
109 | HPstateTmp = X[ decimated_framelength - 1 ]; | ||
110 | for( i = decimated_framelength - 1; i > 0; i-- ) { | ||
111 | X[ i - 1 ] = silk_RSHIFT( X[ i - 1 ], 1 ); | ||
112 | X[ i ] -= X[ i - 1 ]; | ||
113 | } | ||
114 | X[ 0 ] -= psSilk_VAD->HPstate; | ||
115 | psSilk_VAD->HPstate = HPstateTmp; | ||
116 | |||
117 | /*************************************/ | ||
118 | /* Calculate the energy in each band */ | ||
119 | /*************************************/ | ||
120 | for( b = 0; b < VAD_N_BANDS; b++ ) { | ||
121 | /* Find the decimated framelength in the non-uniformly divided bands */ | ||
122 | decimated_framelength = silk_RSHIFT( psEncC->frame_length, silk_min_int( VAD_N_BANDS - b, VAD_N_BANDS - 1 ) ); | ||
123 | |||
124 | /* Split length into subframe lengths */ | ||
125 | dec_subframe_length = silk_RSHIFT( decimated_framelength, VAD_INTERNAL_SUBFRAMES_LOG2 ); | ||
126 | dec_subframe_offset = 0; | ||
127 | |||
128 | /* Compute energy per sub-frame */ | ||
129 | /* initialize with summed energy of last subframe */ | ||
130 | Xnrg[ b ] = psSilk_VAD->XnrgSubfr[ b ]; | ||
131 | for( s = 0; s < VAD_INTERNAL_SUBFRAMES; s++ ) { | ||
132 | __m128i xmm_X, xmm_acc; | ||
133 | sumSquared = 0; | ||
134 | |||
135 | xmm_acc = _mm_setzero_si128(); | ||
136 | |||
137 | for( i = 0; i < dec_subframe_length - 7; i += 8 ) | ||
138 | { | ||
139 | xmm_X = _mm_loadu_si128( (__m128i *)&(X[ X_offset[ b ] + i + dec_subframe_offset ] ) ); | ||
140 | xmm_X = _mm_srai_epi16( xmm_X, 3 ); | ||
141 | xmm_X = _mm_madd_epi16( xmm_X, xmm_X ); | ||
142 | xmm_acc = _mm_add_epi32( xmm_acc, xmm_X ); | ||
143 | } | ||
144 | |||
145 | xmm_acc = _mm_add_epi32( xmm_acc, _mm_unpackhi_epi64( xmm_acc, xmm_acc ) ); | ||
146 | xmm_acc = _mm_add_epi32( xmm_acc, _mm_shufflelo_epi16( xmm_acc, 0x0E ) ); | ||
147 | |||
148 | sumSquared += _mm_cvtsi128_si32( xmm_acc ); | ||
149 | |||
150 | for( ; i < dec_subframe_length; i++ ) { | ||
151 | /* The energy will be less than dec_subframe_length * ( silk_int16_MIN / 8 ) ^ 2. */ | ||
152 | /* Therefore we can accumulate with no risk of overflow (unless dec_subframe_length > 128) */ | ||
153 | x_tmp = silk_RSHIFT( | ||
154 | X[ X_offset[ b ] + i + dec_subframe_offset ], 3 ); | ||
155 | sumSquared = silk_SMLABB( sumSquared, x_tmp, x_tmp ); | ||
156 | |||
157 | /* Safety check */ | ||
158 | silk_assert( sumSquared >= 0 ); | ||
159 | } | ||
160 | |||
161 | /* Add/saturate summed energy of current subframe */ | ||
162 | if( s < VAD_INTERNAL_SUBFRAMES - 1 ) { | ||
163 | Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], sumSquared ); | ||
164 | } else { | ||
165 | /* Look-ahead subframe */ | ||
166 | Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], silk_RSHIFT( sumSquared, 1 ) ); | ||
167 | } | ||
168 | |||
169 | dec_subframe_offset += dec_subframe_length; | ||
170 | } | ||
171 | psSilk_VAD->XnrgSubfr[ b ] = sumSquared; | ||
172 | } | ||
173 | |||
174 | /********************/ | ||
175 | /* Noise estimation */ | ||
176 | /********************/ | ||
177 | silk_VAD_GetNoiseLevels( &Xnrg[ 0 ], psSilk_VAD ); | ||
178 | |||
179 | /***********************************************/ | ||
180 | /* Signal-plus-noise to noise ratio estimation */ | ||
181 | /***********************************************/ | ||
182 | sumSquared = 0; | ||
183 | input_tilt = 0; | ||
184 | for( b = 0; b < VAD_N_BANDS; b++ ) { | ||
185 | speech_nrg = Xnrg[ b ] - psSilk_VAD->NL[ b ]; | ||
186 | if( speech_nrg > 0 ) { | ||
187 | /* Divide, with sufficient resolution */ | ||
188 | if( ( Xnrg[ b ] & 0xFF800000 ) == 0 ) { | ||
189 | NrgToNoiseRatio_Q8[ b ] = silk_DIV32( silk_LSHIFT( Xnrg[ b ], 8 ), psSilk_VAD->NL[ b ] + 1 ); | ||
190 | } else { | ||
191 | NrgToNoiseRatio_Q8[ b ] = silk_DIV32( Xnrg[ b ], silk_RSHIFT( psSilk_VAD->NL[ b ], 8 ) + 1 ); | ||
192 | } | ||
193 | |||
194 | /* Convert to log domain */ | ||
195 | SNR_Q7 = silk_lin2log( NrgToNoiseRatio_Q8[ b ] ) - 8 * 128; | ||
196 | |||
197 | /* Sum-of-squares */ | ||
198 | sumSquared = silk_SMLABB( sumSquared, SNR_Q7, SNR_Q7 ); /* Q14 */ | ||
199 | |||
200 | /* Tilt measure */ | ||
201 | if( speech_nrg < ( (opus_int32)1 << 20 ) ) { | ||
202 | /* Scale down SNR value for small subband speech energies */ | ||
203 | SNR_Q7 = silk_SMULWB( silk_LSHIFT( silk_SQRT_APPROX( speech_nrg ), 6 ), SNR_Q7 ); | ||
204 | } | ||
205 | input_tilt = silk_SMLAWB( input_tilt, tiltWeights[ b ], SNR_Q7 ); | ||
206 | } else { | ||
207 | NrgToNoiseRatio_Q8[ b ] = 256; | ||
208 | } | ||
209 | } | ||
210 | |||
211 | /* Mean-of-squares */ | ||
212 | sumSquared = silk_DIV32_16( sumSquared, VAD_N_BANDS ); /* Q14 */ | ||
213 | |||
214 | /* Root-mean-square approximation, scale to dBs, and write to output pointer */ | ||
215 | pSNR_dB_Q7 = (opus_int16)( 3 * silk_SQRT_APPROX( sumSquared ) ); /* Q7 */ | ||
216 | |||
217 | /*********************************/ | ||
218 | /* Speech Probability Estimation */ | ||
219 | /*********************************/ | ||
220 | SA_Q15 = silk_sigm_Q15( silk_SMULWB( VAD_SNR_FACTOR_Q16, pSNR_dB_Q7 ) - VAD_NEGATIVE_OFFSET_Q5 ); | ||
221 | |||
222 | /**************************/ | ||
223 | /* Frequency Tilt Measure */ | ||
224 | /**************************/ | ||
225 | psEncC->input_tilt_Q15 = silk_LSHIFT( silk_sigm_Q15( input_tilt ) - 16384, 1 ); | ||
226 | |||
227 | /**************************************************/ | ||
228 | /* Scale the sigmoid output based on power levels */ | ||
229 | /**************************************************/ | ||
230 | speech_nrg = 0; | ||
231 | for( b = 0; b < VAD_N_BANDS; b++ ) { | ||
232 | /* Accumulate signal-without-noise energies, higher frequency bands have more weight */ | ||
233 | speech_nrg += ( b + 1 ) * silk_RSHIFT( Xnrg[ b ] - psSilk_VAD->NL[ b ], 4 ); | ||
234 | } | ||
235 | |||
236 | /* Power scaling */ | ||
237 | if( speech_nrg <= 0 ) { | ||
238 | SA_Q15 = silk_RSHIFT( SA_Q15, 1 ); | ||
239 | } else if( speech_nrg < 32768 ) { | ||
240 | if( psEncC->frame_length == 10 * psEncC->fs_kHz ) { | ||
241 | speech_nrg = silk_LSHIFT_SAT32( speech_nrg, 16 ); | ||
242 | } else { | ||
243 | speech_nrg = silk_LSHIFT_SAT32( speech_nrg, 15 ); | ||
244 | } | ||
245 | |||
246 | /* square-root */ | ||
247 | speech_nrg = silk_SQRT_APPROX( speech_nrg ); | ||
248 | SA_Q15 = silk_SMULWB( 32768 + speech_nrg, SA_Q15 ); | ||
249 | } | ||
250 | |||
251 | /* Copy the resulting speech activity in Q8 */ | ||
252 | psEncC->speech_activity_Q8 = silk_min_int( silk_RSHIFT( SA_Q15, 7 ), silk_uint8_MAX ); | ||
253 | |||
254 | /***********************************/ | ||
255 | /* Energy Level and SNR estimation */ | ||
256 | /***********************************/ | ||
257 | /* Smoothing coefficient */ | ||
258 | smooth_coef_Q16 = silk_SMULWB( VAD_SNR_SMOOTH_COEF_Q18, silk_SMULWB( (opus_int32)SA_Q15, SA_Q15 ) ); | ||
259 | |||
260 | if( psEncC->frame_length == 10 * psEncC->fs_kHz ) { | ||
261 | smooth_coef_Q16 >>= 1; | ||
262 | } | ||
263 | |||
264 | for( b = 0; b < VAD_N_BANDS; b++ ) { | ||
265 | /* compute smoothed energy-to-noise ratio per band */ | ||
266 | psSilk_VAD->NrgRatioSmth_Q8[ b ] = silk_SMLAWB( psSilk_VAD->NrgRatioSmth_Q8[ b ], | ||
267 | NrgToNoiseRatio_Q8[ b ] - psSilk_VAD->NrgRatioSmth_Q8[ b ], smooth_coef_Q16 ); | ||
268 | |||
269 | /* signal to noise ratio in dB per band */ | ||
270 | SNR_Q7 = 3 * ( silk_lin2log( psSilk_VAD->NrgRatioSmth_Q8[b] ) - 8 * 128 ); | ||
271 | /* quality = sigmoid( 0.25 * ( SNR_dB - 16 ) ); */ | ||
272 | psEncC->input_quality_bands_Q15[ b ] = silk_sigm_Q15( silk_RSHIFT( SNR_Q7 - 16 * 128, 4 ) ); | ||
273 | } | ||
274 | |||
275 | RESTORE_STACK; | ||
276 | return( ret ); | ||
277 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/x86/VQ_WMat_EC_sse4_1.c b/lib/rbcodec/codecs/libopus/silk/x86/VQ_WMat_EC_sse4_1.c new file mode 100644 index 0000000000..74d6c6d0ec --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/x86/VQ_WMat_EC_sse4_1.c | |||
@@ -0,0 +1,142 @@ | |||
1 | /* Copyright (c) 2014, Cisco Systems, INC | ||
2 | Written by XiangMingZhu WeiZhou MinPeng YanWang | ||
3 | |||
4 | Redistribution and use in source and binary forms, with or without | ||
5 | modification, are permitted provided that the following conditions | ||
6 | are met: | ||
7 | |||
8 | - Redistributions of source code must retain the above copyright | ||
9 | notice, this list of conditions and the following disclaimer. | ||
10 | |||
11 | - Redistributions in binary form must reproduce the above copyright | ||
12 | notice, this list of conditions and the following disclaimer in the | ||
13 | documentation and/or other materials provided with the distribution. | ||
14 | |||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
16 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
17 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
18 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER | ||
19 | OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
20 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
21 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
22 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
23 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
24 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include <xmmintrin.h> | ||
33 | #include <emmintrin.h> | ||
34 | #include <smmintrin.h> | ||
35 | #include "main.h" | ||
36 | #include "celt/x86/x86cpu.h" | ||
37 | |||
38 | /* Entropy constrained matrix-weighted VQ, hard-coded to 5-element vectors, for a single input data vector */ | ||
39 | void silk_VQ_WMat_EC_sse4_1( | ||
40 | opus_int8 *ind, /* O index of best codebook vector */ | ||
41 | opus_int32 *rate_dist_Q14, /* O best weighted quant error + mu * rate */ | ||
42 | opus_int *gain_Q7, /* O sum of absolute LTP coefficients */ | ||
43 | const opus_int16 *in_Q14, /* I input vector to be quantized */ | ||
44 | const opus_int32 *W_Q18, /* I weighting matrix */ | ||
45 | const opus_int8 *cb_Q7, /* I codebook */ | ||
46 | const opus_uint8 *cb_gain_Q7, /* I codebook effective gain */ | ||
47 | const opus_uint8 *cl_Q5, /* I code length for each codebook vector */ | ||
48 | const opus_int mu_Q9, /* I tradeoff betw. weighted error and rate */ | ||
49 | const opus_int32 max_gain_Q7, /* I maximum sum of absolute LTP coefficients */ | ||
50 | opus_int L /* I number of vectors in codebook */ | ||
51 | ) | ||
52 | { | ||
53 | opus_int k, gain_tmp_Q7; | ||
54 | const opus_int8 *cb_row_Q7; | ||
55 | opus_int16 diff_Q14[ 5 ]; | ||
56 | opus_int32 sum1_Q14, sum2_Q16; | ||
57 | |||
58 | __m128i C_tmp1, C_tmp2, C_tmp3, C_tmp4, C_tmp5; | ||
59 | /* Loop over codebook */ | ||
60 | *rate_dist_Q14 = silk_int32_MAX; | ||
61 | cb_row_Q7 = cb_Q7; | ||
62 | for( k = 0; k < L; k++ ) { | ||
63 | gain_tmp_Q7 = cb_gain_Q7[k]; | ||
64 | |||
65 | diff_Q14[ 0 ] = in_Q14[ 0 ] - silk_LSHIFT( cb_row_Q7[ 0 ], 7 ); | ||
66 | |||
67 | C_tmp1 = OP_CVTEPI16_EPI32_M64( &in_Q14[ 1 ] ); | ||
68 | C_tmp2 = OP_CVTEPI8_EPI32_M32( &cb_row_Q7[ 1 ] ); | ||
69 | C_tmp2 = _mm_slli_epi32( C_tmp2, 7 ); | ||
70 | C_tmp1 = _mm_sub_epi32( C_tmp1, C_tmp2 ); | ||
71 | |||
72 | diff_Q14[ 1 ] = _mm_extract_epi16( C_tmp1, 0 ); | ||
73 | diff_Q14[ 2 ] = _mm_extract_epi16( C_tmp1, 2 ); | ||
74 | diff_Q14[ 3 ] = _mm_extract_epi16( C_tmp1, 4 ); | ||
75 | diff_Q14[ 4 ] = _mm_extract_epi16( C_tmp1, 6 ); | ||
76 | |||
77 | /* Weighted rate */ | ||
78 | sum1_Q14 = silk_SMULBB( mu_Q9, cl_Q5[ k ] ); | ||
79 | |||
80 | /* Penalty for too large gain */ | ||
81 | sum1_Q14 = silk_ADD_LSHIFT32( sum1_Q14, silk_max( silk_SUB32( gain_tmp_Q7, max_gain_Q7 ), 0 ), 10 ); | ||
82 | |||
83 | silk_assert( sum1_Q14 >= 0 ); | ||
84 | |||
85 | /* first row of W_Q18 */ | ||
86 | C_tmp3 = _mm_loadu_si128( (__m128i *)(&W_Q18[ 1 ] ) ); | ||
87 | C_tmp4 = _mm_mul_epi32( C_tmp3, C_tmp1 ); | ||
88 | C_tmp4 = _mm_srli_si128( C_tmp4, 2 ); | ||
89 | |||
90 | C_tmp1 = _mm_shuffle_epi32( C_tmp1, _MM_SHUFFLE( 0, 3, 2, 1 ) ); /* shift right 4 bytes */ | ||
91 | C_tmp3 = _mm_shuffle_epi32( C_tmp3, _MM_SHUFFLE( 0, 3, 2, 1 ) ); /* shift right 4 bytes */ | ||
92 | |||
93 | C_tmp5 = _mm_mul_epi32( C_tmp3, C_tmp1 ); | ||
94 | C_tmp5 = _mm_srli_si128( C_tmp5, 2 ); | ||
95 | |||
96 | C_tmp5 = _mm_add_epi32( C_tmp4, C_tmp5 ); | ||
97 | C_tmp5 = _mm_slli_epi32( C_tmp5, 1 ); | ||
98 | |||
99 | C_tmp5 = _mm_add_epi32( C_tmp5, _mm_shuffle_epi32( C_tmp5, _MM_SHUFFLE( 0, 0, 0, 2 ) ) ); | ||
100 | sum2_Q16 = _mm_cvtsi128_si32( C_tmp5 ); | ||
101 | |||
102 | sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 0 ], diff_Q14[ 0 ] ); | ||
103 | sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 0 ] ); | ||
104 | |||
105 | /* second row of W_Q18 */ | ||
106 | sum2_Q16 = silk_SMULWB( W_Q18[ 7 ], diff_Q14[ 2 ] ); | ||
107 | sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 8 ], diff_Q14[ 3 ] ); | ||
108 | sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 9 ], diff_Q14[ 4 ] ); | ||
109 | sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 ); | ||
110 | sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 6 ], diff_Q14[ 1 ] ); | ||
111 | sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 1 ] ); | ||
112 | |||
113 | /* third row of W_Q18 */ | ||
114 | sum2_Q16 = silk_SMULWB( W_Q18[ 13 ], diff_Q14[ 3 ] ); | ||
115 | sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 14 ], diff_Q14[ 4 ] ); | ||
116 | sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 ); | ||
117 | sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 12 ], diff_Q14[ 2 ] ); | ||
118 | sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 2 ] ); | ||
119 | |||
120 | /* fourth row of W_Q18 */ | ||
121 | sum2_Q16 = silk_SMULWB( W_Q18[ 19 ], diff_Q14[ 4 ] ); | ||
122 | sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 ); | ||
123 | sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 18 ], diff_Q14[ 3 ] ); | ||
124 | sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 3 ] ); | ||
125 | |||
126 | /* last row of W_Q18 */ | ||
127 | sum2_Q16 = silk_SMULWB( W_Q18[ 24 ], diff_Q14[ 4 ] ); | ||
128 | sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 4 ] ); | ||
129 | |||
130 | silk_assert( sum1_Q14 >= 0 ); | ||
131 | |||
132 | /* find best */ | ||
133 | if( sum1_Q14 < *rate_dist_Q14 ) { | ||
134 | *rate_dist_Q14 = sum1_Q14; | ||
135 | *ind = (opus_int8)k; | ||
136 | *gain_Q7 = gain_tmp_Q7; | ||
137 | } | ||
138 | |||
139 | /* Go to next cbk vector */ | ||
140 | cb_row_Q7 += LTP_ORDER; | ||
141 | } | ||
142 | } | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/x86/main_sse.h b/lib/rbcodec/codecs/libopus/silk/x86/main_sse.h new file mode 100644 index 0000000000..2f15d44869 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/x86/main_sse.h | |||
@@ -0,0 +1,248 @@ | |||
1 | /* Copyright (c) 2014, Cisco Systems, INC | ||
2 | Written by XiangMingZhu WeiZhou MinPeng YanWang | ||
3 | |||
4 | Redistribution and use in source and binary forms, with or without | ||
5 | modification, are permitted provided that the following conditions | ||
6 | are met: | ||
7 | |||
8 | - Redistributions of source code must retain the above copyright | ||
9 | notice, this list of conditions and the following disclaimer. | ||
10 | |||
11 | - Redistributions in binary form must reproduce the above copyright | ||
12 | notice, this list of conditions and the following disclaimer in the | ||
13 | documentation and/or other materials provided with the distribution. | ||
14 | |||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
16 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
17 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
18 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER | ||
19 | OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
20 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
21 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
22 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
23 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
24 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | #ifndef MAIN_SSE_H | ||
29 | #define MAIN_SSE_H | ||
30 | |||
31 | #ifdef HAVE_CONFIG_H | ||
32 | #include "config.h" | ||
33 | #endif | ||
34 | |||
35 | # if defined(OPUS_X86_MAY_HAVE_SSE4_1) | ||
36 | |||
37 | #if 0 /* FIXME: SSE disabled until silk_VQ_WMat_EC_sse4_1() gets updated. */ | ||
38 | # define OVERRIDE_silk_VQ_WMat_EC | ||
39 | |||
40 | void silk_VQ_WMat_EC_sse4_1( | ||
41 | opus_int8 *ind, /* O index of best codebook vector */ | ||
42 | opus_int32 *rate_dist_Q14, /* O best weighted quant error + mu * rate */ | ||
43 | opus_int *gain_Q7, /* O sum of absolute LTP coefficients */ | ||
44 | const opus_int16 *in_Q14, /* I input vector to be quantized */ | ||
45 | const opus_int32 *W_Q18, /* I weighting matrix */ | ||
46 | const opus_int8 *cb_Q7, /* I codebook */ | ||
47 | const opus_uint8 *cb_gain_Q7, /* I codebook effective gain */ | ||
48 | const opus_uint8 *cl_Q5, /* I code length for each codebook vector */ | ||
49 | const opus_int mu_Q9, /* I tradeoff betw. weighted error and rate */ | ||
50 | const opus_int32 max_gain_Q7, /* I maximum sum of absolute LTP coefficients */ | ||
51 | opus_int L /* I number of vectors in codebook */ | ||
52 | ); | ||
53 | |||
54 | #if defined OPUS_X86_PRESUME_SSE4_1 | ||
55 | |||
56 | #define silk_VQ_WMat_EC(ind, rate_dist_Q14, gain_Q7, in_Q14, W_Q18, cb_Q7, cb_gain_Q7, cl_Q5, \ | ||
57 | mu_Q9, max_gain_Q7, L, arch) \ | ||
58 | ((void)(arch),silk_VQ_WMat_EC_sse4_1(ind, rate_dist_Q14, gain_Q7, in_Q14, W_Q18, cb_Q7, cb_gain_Q7, cl_Q5, \ | ||
59 | mu_Q9, max_gain_Q7, L)) | ||
60 | |||
61 | #else | ||
62 | |||
63 | extern void (*const SILK_VQ_WMAT_EC_IMPL[OPUS_ARCHMASK + 1])( | ||
64 | opus_int8 *ind, /* O index of best codebook vector */ | ||
65 | opus_int32 *rate_dist_Q14, /* O best weighted quant error + mu * rate */ | ||
66 | opus_int *gain_Q7, /* O sum of absolute LTP coefficients */ | ||
67 | const opus_int16 *in_Q14, /* I input vector to be quantized */ | ||
68 | const opus_int32 *W_Q18, /* I weighting matrix */ | ||
69 | const opus_int8 *cb_Q7, /* I codebook */ | ||
70 | const opus_uint8 *cb_gain_Q7, /* I codebook effective gain */ | ||
71 | const opus_uint8 *cl_Q5, /* I code length for each codebook vector */ | ||
72 | const opus_int mu_Q9, /* I tradeoff betw. weighted error and rate */ | ||
73 | const opus_int32 max_gain_Q7, /* I maximum sum of absolute LTP coefficients */ | ||
74 | opus_int L /* I number of vectors in codebook */ | ||
75 | ); | ||
76 | |||
77 | # define silk_VQ_WMat_EC(ind, rate_dist_Q14, gain_Q7, in_Q14, W_Q18, cb_Q7, cb_gain_Q7, cl_Q5, \ | ||
78 | mu_Q9, max_gain_Q7, L, arch) \ | ||
79 | ((*SILK_VQ_WMAT_EC_IMPL[(arch) & OPUS_ARCHMASK])(ind, rate_dist_Q14, gain_Q7, in_Q14, W_Q18, cb_Q7, cb_gain_Q7, cl_Q5, \ | ||
80 | mu_Q9, max_gain_Q7, L)) | ||
81 | |||
82 | #endif | ||
83 | #endif | ||
84 | |||
85 | #if 0 /* FIXME: SSE disabled until the NSQ code gets updated. */ | ||
86 | # define OVERRIDE_silk_NSQ | ||
87 | |||
88 | void silk_NSQ_sse4_1( | ||
89 | const silk_encoder_state *psEncC, /* I Encoder State */ | ||
90 | silk_nsq_state *NSQ, /* I/O NSQ state */ | ||
91 | SideInfoIndices *psIndices, /* I/O Quantization Indices */ | ||
92 | const opus_int32 x_Q3[], /* I Prefiltered input signal */ | ||
93 | opus_int8 pulses[], /* O Quantized pulse signal */ | ||
94 | const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ | ||
95 | const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ | ||
96 | const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ | ||
97 | const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ | ||
98 | const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ | ||
99 | const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ | ||
100 | const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ | ||
101 | const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ | ||
102 | const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ | ||
103 | const opus_int LTP_scale_Q14 /* I LTP state scaling */ | ||
104 | ); | ||
105 | |||
106 | #if defined OPUS_X86_PRESUME_SSE4_1 | ||
107 | |||
108 | #define silk_NSQ(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \ | ||
109 | HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \ | ||
110 | ((void)(arch),silk_NSQ_sse4_1(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \ | ||
111 | HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14)) | ||
112 | |||
113 | #else | ||
114 | |||
115 | extern void (*const SILK_NSQ_IMPL[OPUS_ARCHMASK + 1])( | ||
116 | const silk_encoder_state *psEncC, /* I Encoder State */ | ||
117 | silk_nsq_state *NSQ, /* I/O NSQ state */ | ||
118 | SideInfoIndices *psIndices, /* I/O Quantization Indices */ | ||
119 | const opus_int32 x_Q3[], /* I Prefiltered input signal */ | ||
120 | opus_int8 pulses[], /* O Quantized pulse signal */ | ||
121 | const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ | ||
122 | const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ | ||
123 | const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ | ||
124 | const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ | ||
125 | const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ | ||
126 | const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ | ||
127 | const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ | ||
128 | const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ | ||
129 | const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ | ||
130 | const opus_int LTP_scale_Q14 /* I LTP state scaling */ | ||
131 | ); | ||
132 | |||
133 | # define silk_NSQ(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \ | ||
134 | HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \ | ||
135 | ((*SILK_NSQ_IMPL[(arch) & OPUS_ARCHMASK])(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \ | ||
136 | HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14)) | ||
137 | |||
138 | #endif | ||
139 | |||
140 | # define OVERRIDE_silk_NSQ_del_dec | ||
141 | |||
142 | void silk_NSQ_del_dec_sse4_1( | ||
143 | const silk_encoder_state *psEncC, /* I Encoder State */ | ||
144 | silk_nsq_state *NSQ, /* I/O NSQ state */ | ||
145 | SideInfoIndices *psIndices, /* I/O Quantization Indices */ | ||
146 | const opus_int32 x_Q3[], /* I Prefiltered input signal */ | ||
147 | opus_int8 pulses[], /* O Quantized pulse signal */ | ||
148 | const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ | ||
149 | const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ | ||
150 | const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ | ||
151 | const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ | ||
152 | const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ | ||
153 | const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ | ||
154 | const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ | ||
155 | const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ | ||
156 | const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ | ||
157 | const opus_int LTP_scale_Q14 /* I LTP state scaling */ | ||
158 | ); | ||
159 | |||
160 | #if defined OPUS_X86_PRESUME_SSE4_1 | ||
161 | |||
162 | #define silk_NSQ_del_dec(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \ | ||
163 | HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \ | ||
164 | ((void)(arch),silk_NSQ_del_dec_sse4_1(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \ | ||
165 | HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14)) | ||
166 | |||
167 | #else | ||
168 | |||
169 | extern void (*const SILK_NSQ_DEL_DEC_IMPL[OPUS_ARCHMASK + 1])( | ||
170 | const silk_encoder_state *psEncC, /* I Encoder State */ | ||
171 | silk_nsq_state *NSQ, /* I/O NSQ state */ | ||
172 | SideInfoIndices *psIndices, /* I/O Quantization Indices */ | ||
173 | const opus_int32 x_Q3[], /* I Prefiltered input signal */ | ||
174 | opus_int8 pulses[], /* O Quantized pulse signal */ | ||
175 | const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ | ||
176 | const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ | ||
177 | const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ | ||
178 | const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ | ||
179 | const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ | ||
180 | const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ | ||
181 | const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ | ||
182 | const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ | ||
183 | const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ | ||
184 | const opus_int LTP_scale_Q14 /* I LTP state scaling */ | ||
185 | ); | ||
186 | |||
187 | # define silk_NSQ_del_dec(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \ | ||
188 | HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \ | ||
189 | ((*SILK_NSQ_DEL_DEC_IMPL[(arch) & OPUS_ARCHMASK])(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \ | ||
190 | HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14)) | ||
191 | |||
192 | #endif | ||
193 | #endif | ||
194 | |||
195 | void silk_noise_shape_quantizer( | ||
196 | silk_nsq_state *NSQ, /* I/O NSQ state */ | ||
197 | opus_int signalType, /* I Signal type */ | ||
198 | const opus_int32 x_sc_Q10[], /* I */ | ||
199 | opus_int8 pulses[], /* O */ | ||
200 | opus_int16 xq[], /* O */ | ||
201 | opus_int32 sLTP_Q15[], /* I/O LTP state */ | ||
202 | const opus_int16 a_Q12[], /* I Short term prediction coefs */ | ||
203 | const opus_int16 b_Q14[], /* I Long term prediction coefs */ | ||
204 | const opus_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */ | ||
205 | opus_int lag, /* I Pitch lag */ | ||
206 | opus_int32 HarmShapeFIRPacked_Q14, /* I */ | ||
207 | opus_int Tilt_Q14, /* I Spectral tilt */ | ||
208 | opus_int32 LF_shp_Q14, /* I */ | ||
209 | opus_int32 Gain_Q16, /* I */ | ||
210 | opus_int Lambda_Q10, /* I */ | ||
211 | opus_int offset_Q10, /* I */ | ||
212 | opus_int length, /* I Input length */ | ||
213 | opus_int shapingLPCOrder, /* I Noise shaping AR filter order */ | ||
214 | opus_int predictLPCOrder, /* I Prediction filter order */ | ||
215 | int arch /* I Architecture */ | ||
216 | ); | ||
217 | |||
218 | /**************************/ | ||
219 | /* Noise level estimation */ | ||
220 | /**************************/ | ||
221 | void silk_VAD_GetNoiseLevels( | ||
222 | const opus_int32 pX[ VAD_N_BANDS ], /* I subband energies */ | ||
223 | silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */ | ||
224 | ); | ||
225 | |||
226 | # define OVERRIDE_silk_VAD_GetSA_Q8 | ||
227 | |||
228 | opus_int silk_VAD_GetSA_Q8_sse4_1( | ||
229 | silk_encoder_state *psEnC, | ||
230 | const opus_int16 pIn[] | ||
231 | ); | ||
232 | |||
233 | #if defined(OPUS_X86_PRESUME_SSE4_1) | ||
234 | #define silk_VAD_GetSA_Q8(psEnC, pIn, arch) ((void)(arch),silk_VAD_GetSA_Q8_sse4_1(psEnC, pIn)) | ||
235 | |||
236 | #else | ||
237 | |||
238 | # define silk_VAD_GetSA_Q8(psEnC, pIn, arch) \ | ||
239 | ((*SILK_VAD_GETSA_Q8_IMPL[(arch) & OPUS_ARCHMASK])(psEnC, pIn)) | ||
240 | |||
241 | extern opus_int (*const SILK_VAD_GETSA_Q8_IMPL[OPUS_ARCHMASK + 1])( | ||
242 | silk_encoder_state *psEnC, | ||
243 | const opus_int16 pIn[]); | ||
244 | |||
245 | #endif | ||
246 | |||
247 | # endif | ||
248 | #endif | ||
diff --git a/lib/rbcodec/codecs/libopus/silk/x86/x86_silk_map.c b/lib/rbcodec/codecs/libopus/silk/x86/x86_silk_map.c new file mode 100644 index 0000000000..32dcc3cab7 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/x86/x86_silk_map.c | |||
@@ -0,0 +1,164 @@ | |||
1 | /* Copyright (c) 2014, Cisco Systems, INC | ||
2 | Written by XiangMingZhu WeiZhou MinPeng YanWang | ||
3 | |||
4 | Redistribution and use in source and binary forms, with or without | ||
5 | modification, are permitted provided that the following conditions | ||
6 | are met: | ||
7 | |||
8 | - Redistributions of source code must retain the above copyright | ||
9 | notice, this list of conditions and the following disclaimer. | ||
10 | |||
11 | - Redistributions in binary form must reproduce the above copyright | ||
12 | notice, this list of conditions and the following disclaimer in the | ||
13 | documentation and/or other materials provided with the distribution. | ||
14 | |||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
16 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
17 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
18 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER | ||
19 | OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
20 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
21 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
22 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
23 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
24 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | #if defined(HAVE_CONFIG_H) | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "celt/x86/x86cpu.h" | ||
33 | #include "structs.h" | ||
34 | #include "SigProc_FIX.h" | ||
35 | #include "pitch.h" | ||
36 | #include "main.h" | ||
37 | |||
38 | #if !defined(OPUS_X86_PRESUME_SSE4_1) | ||
39 | |||
40 | #if defined(FIXED_POINT) | ||
41 | |||
42 | #include "fixed/main_FIX.h" | ||
43 | |||
44 | opus_int64 (*const SILK_INNER_PROD16_ALIGNED_64_IMPL[ OPUS_ARCHMASK + 1 ] )( | ||
45 | const opus_int16 *inVec1, | ||
46 | const opus_int16 *inVec2, | ||
47 | const opus_int len | ||
48 | ) = { | ||
49 | silk_inner_prod16_aligned_64_c, /* non-sse */ | ||
50 | silk_inner_prod16_aligned_64_c, | ||
51 | silk_inner_prod16_aligned_64_c, | ||
52 | MAY_HAVE_SSE4_1( silk_inner_prod16_aligned_64 ), /* sse4.1 */ | ||
53 | MAY_HAVE_SSE4_1( silk_inner_prod16_aligned_64 ) /* avx */ | ||
54 | }; | ||
55 | |||
56 | #endif | ||
57 | |||
58 | opus_int (*const SILK_VAD_GETSA_Q8_IMPL[ OPUS_ARCHMASK + 1 ] )( | ||
59 | silk_encoder_state *psEncC, | ||
60 | const opus_int16 pIn[] | ||
61 | ) = { | ||
62 | silk_VAD_GetSA_Q8_c, /* non-sse */ | ||
63 | silk_VAD_GetSA_Q8_c, | ||
64 | silk_VAD_GetSA_Q8_c, | ||
65 | MAY_HAVE_SSE4_1( silk_VAD_GetSA_Q8 ), /* sse4.1 */ | ||
66 | MAY_HAVE_SSE4_1( silk_VAD_GetSA_Q8 ) /* avx */ | ||
67 | }; | ||
68 | |||
69 | #if 0 /* FIXME: SSE disabled until the NSQ code gets updated. */ | ||
70 | void (*const SILK_NSQ_IMPL[ OPUS_ARCHMASK + 1 ] )( | ||
71 | const silk_encoder_state *psEncC, /* I Encoder State */ | ||
72 | silk_nsq_state *NSQ, /* I/O NSQ state */ | ||
73 | SideInfoIndices *psIndices, /* I/O Quantization Indices */ | ||
74 | const opus_int32 x_Q3[], /* I Prefiltered input signal */ | ||
75 | opus_int8 pulses[], /* O Quantized pulse signal */ | ||
76 | const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ | ||
77 | const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ | ||
78 | const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ | ||
79 | const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ | ||
80 | const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ | ||
81 | const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ | ||
82 | const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ | ||
83 | const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ | ||
84 | const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ | ||
85 | const opus_int LTP_scale_Q14 /* I LTP state scaling */ | ||
86 | ) = { | ||
87 | silk_NSQ_c, /* non-sse */ | ||
88 | silk_NSQ_c, | ||
89 | silk_NSQ_c, | ||
90 | MAY_HAVE_SSE4_1( silk_NSQ ), /* sse4.1 */ | ||
91 | MAY_HAVE_SSE4_1( silk_NSQ ) /* avx */ | ||
92 | }; | ||
93 | #endif | ||
94 | |||
95 | #if 0 /* FIXME: SSE disabled until silk_VQ_WMat_EC_sse4_1() gets updated. */ | ||
96 | void (*const SILK_VQ_WMAT_EC_IMPL[ OPUS_ARCHMASK + 1 ] )( | ||
97 | opus_int8 *ind, /* O index of best codebook vector */ | ||
98 | opus_int32 *rate_dist_Q14, /* O best weighted quant error + mu * rate */ | ||
99 | opus_int *gain_Q7, /* O sum of absolute LTP coefficients */ | ||
100 | const opus_int16 *in_Q14, /* I input vector to be quantized */ | ||
101 | const opus_int32 *W_Q18, /* I weighting matrix */ | ||
102 | const opus_int8 *cb_Q7, /* I codebook */ | ||
103 | const opus_uint8 *cb_gain_Q7, /* I codebook effective gain */ | ||
104 | const opus_uint8 *cl_Q5, /* I code length for each codebook vector */ | ||
105 | const opus_int mu_Q9, /* I tradeoff betw. weighted error and rate */ | ||
106 | const opus_int32 max_gain_Q7, /* I maximum sum of absolute LTP coefficients */ | ||
107 | opus_int L /* I number of vectors in codebook */ | ||
108 | ) = { | ||
109 | silk_VQ_WMat_EC_c, /* non-sse */ | ||
110 | silk_VQ_WMat_EC_c, | ||
111 | silk_VQ_WMat_EC_c, | ||
112 | MAY_HAVE_SSE4_1( silk_VQ_WMat_EC ), /* sse4.1 */ | ||
113 | MAY_HAVE_SSE4_1( silk_VQ_WMat_EC ) /* avx */ | ||
114 | }; | ||
115 | #endif | ||
116 | |||
117 | #if 0 /* FIXME: SSE disabled until the NSQ code gets updated. */ | ||
118 | void (*const SILK_NSQ_DEL_DEC_IMPL[ OPUS_ARCHMASK + 1 ] )( | ||
119 | const silk_encoder_state *psEncC, /* I Encoder State */ | ||
120 | silk_nsq_state *NSQ, /* I/O NSQ state */ | ||
121 | SideInfoIndices *psIndices, /* I/O Quantization Indices */ | ||
122 | const opus_int32 x_Q3[], /* I Prefiltered input signal */ | ||
123 | opus_int8 pulses[], /* O Quantized pulse signal */ | ||
124 | const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ | ||
125 | const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ | ||
126 | const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ | ||
127 | const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ | ||
128 | const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ | ||
129 | const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ | ||
130 | const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ | ||
131 | const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ | ||
132 | const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ | ||
133 | const opus_int LTP_scale_Q14 /* I LTP state scaling */ | ||
134 | ) = { | ||
135 | silk_NSQ_del_dec_c, /* non-sse */ | ||
136 | silk_NSQ_del_dec_c, | ||
137 | silk_NSQ_del_dec_c, | ||
138 | MAY_HAVE_SSE4_1( silk_NSQ_del_dec ), /* sse4.1 */ | ||
139 | MAY_HAVE_SSE4_1( silk_NSQ_del_dec ) /* avx */ | ||
140 | }; | ||
141 | #endif | ||
142 | |||
143 | #if defined(FIXED_POINT) | ||
144 | |||
145 | void (*const SILK_BURG_MODIFIED_IMPL[ OPUS_ARCHMASK + 1 ] )( | ||
146 | opus_int32 *res_nrg, /* O Residual energy */ | ||
147 | opus_int *res_nrg_Q, /* O Residual energy Q value */ | ||
148 | opus_int32 A_Q16[], /* O Prediction coefficients (length order) */ | ||
149 | const opus_int16 x[], /* I Input signal, length: nb_subfr * ( D + subfr_length ) */ | ||
150 | const opus_int32 minInvGain_Q30, /* I Inverse of max prediction gain */ | ||
151 | const opus_int subfr_length, /* I Input signal subframe length (incl. D preceding samples) */ | ||
152 | const opus_int nb_subfr, /* I Number of subframes stacked in x */ | ||
153 | const opus_int D, /* I Order */ | ||
154 | int arch /* I Run-time architecture */ | ||
155 | ) = { | ||
156 | silk_burg_modified_c, /* non-sse */ | ||
157 | silk_burg_modified_c, | ||
158 | silk_burg_modified_c, | ||
159 | MAY_HAVE_SSE4_1( silk_burg_modified ), /* sse4.1 */ | ||
160 | MAY_HAVE_SSE4_1( silk_burg_modified ) /* avx */ | ||
161 | }; | ||
162 | |||
163 | #endif | ||
164 | #endif | ||