diff options
Diffstat (limited to 'lib/rbcodec/codecs/libopus/silk/SigProc_FIX.h')
-rw-r--r-- | lib/rbcodec/codecs/libopus/silk/SigProc_FIX.h | 589 |
1 files changed, 589 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libopus/silk/SigProc_FIX.h b/lib/rbcodec/codecs/libopus/silk/SigProc_FIX.h new file mode 100644 index 0000000000..72ec26a67f --- /dev/null +++ b/lib/rbcodec/codecs/libopus/silk/SigProc_FIX.h | |||
@@ -0,0 +1,589 @@ | |||
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_H | ||
29 | #define SILK_SIGPROC_FIX_H | ||
30 | |||
31 | #ifdef __cplusplus | ||
32 | extern "C" | ||
33 | { | ||
34 | #endif | ||
35 | |||
36 | /*#define silk_MACRO_COUNT */ /* Used to enable WMOPS counting */ | ||
37 | |||
38 | #define SILK_MAX_ORDER_LPC 16 /* max order of the LPC analysis in schur() and k2a() */ | ||
39 | |||
40 | #include <string.h> /* for memset(), memcpy(), memmove() */ | ||
41 | #include "typedef.h" | ||
42 | #include "resampler_structs.h" | ||
43 | #include "macros.h" | ||
44 | |||
45 | |||
46 | /********************************************************************/ | ||
47 | /* SIGNAL PROCESSING FUNCTIONS */ | ||
48 | /********************************************************************/ | ||
49 | |||
50 | /*! | ||
51 | * Initialize/reset the resampler state for a given pair of input/output sampling rates | ||
52 | */ | ||
53 | opus_int silk_resampler_init( | ||
54 | silk_resampler_state_struct *S, /* I/O Resampler state */ | ||
55 | opus_int32 Fs_Hz_in, /* I Input sampling rate (Hz) */ | ||
56 | opus_int32 Fs_Hz_out, /* I Output sampling rate (Hz) */ | ||
57 | opus_int forEnc /* I If 1: encoder; if 0: decoder */ | ||
58 | ); | ||
59 | |||
60 | /*! | ||
61 | * Resampler: convert from one sampling rate to another | ||
62 | */ | ||
63 | opus_int silk_resampler( | ||
64 | silk_resampler_state_struct *S, /* I/O Resampler state */ | ||
65 | opus_int16 out[], /* O Output signal */ | ||
66 | const opus_int16 in[], /* I Input signal */ | ||
67 | opus_int32 inLen /* I Number of input samples */ | ||
68 | ); | ||
69 | |||
70 | /*! | ||
71 | * Downsample 2x, mediocre quality | ||
72 | */ | ||
73 | void silk_resampler_down2( | ||
74 | opus_int32 *S, /* I/O State vector [ 2 ] */ | ||
75 | opus_int16 *out, /* O Output signal [ len ] */ | ||
76 | const opus_int16 *in, /* I Input signal [ floor(len/2) ] */ | ||
77 | opus_int32 inLen /* I Number of input samples */ | ||
78 | ); | ||
79 | |||
80 | /*! | ||
81 | * Downsample by a factor 2/3, low quality | ||
82 | */ | ||
83 | void silk_resampler_down2_3( | ||
84 | opus_int32 *S, /* I/O State vector [ 6 ] */ | ||
85 | opus_int16 *out, /* O Output signal [ floor(2*inLen/3) ] */ | ||
86 | const opus_int16 *in, /* I Input signal [ inLen ] */ | ||
87 | opus_int32 inLen /* I Number of input samples */ | ||
88 | ); | ||
89 | |||
90 | /*! | ||
91 | * second order ARMA filter; | ||
92 | * slower than biquad() but uses more precise coefficients | ||
93 | * can handle (slowly) varying coefficients | ||
94 | */ | ||
95 | void silk_biquad_alt( | ||
96 | const opus_int16 *in, /* I input signal */ | ||
97 | const opus_int32 *B_Q28, /* I MA coefficients [3] */ | ||
98 | const opus_int32 *A_Q28, /* I AR coefficients [2] */ | ||
99 | opus_int32 *S, /* I/O State vector [2] */ | ||
100 | opus_int16 *out, /* O output signal */ | ||
101 | const opus_int32 len, /* I signal length (must be even) */ | ||
102 | opus_int stride /* I Operate on interleaved signal if > 1 */ | ||
103 | ); | ||
104 | |||
105 | /* Variable order MA prediction error filter. */ | ||
106 | void silk_LPC_analysis_filter( | ||
107 | opus_int16 *out, /* O Output signal */ | ||
108 | const opus_int16 *in, /* I Input signal */ | ||
109 | const opus_int16 *B, /* I MA prediction coefficients, Q12 [order] */ | ||
110 | const opus_int32 len, /* I Signal length */ | ||
111 | const opus_int32 d /* I Filter order */ | ||
112 | ); | ||
113 | |||
114 | /* Chirp (bandwidth expand) LP AR filter */ | ||
115 | void silk_bwexpander( | ||
116 | opus_int16 *ar, /* I/O AR filter to be expanded (without leading 1) */ | ||
117 | const opus_int d, /* I Length of ar */ | ||
118 | opus_int32 chirp_Q16 /* I Chirp factor (typically in the range 0 to 1) */ | ||
119 | ); | ||
120 | |||
121 | /* Chirp (bandwidth expand) LP AR filter */ | ||
122 | void silk_bwexpander_32( | ||
123 | opus_int32 *ar, /* I/O AR filter to be expanded (without leading 1) */ | ||
124 | const opus_int d, /* I Length of ar */ | ||
125 | opus_int32 chirp_Q16 /* I Chirp factor in Q16 */ | ||
126 | ); | ||
127 | |||
128 | /* Compute inverse of LPC prediction gain, and */ | ||
129 | /* 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 */ | ||
131 | const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */ | ||
132 | const opus_int order /* I Prediction order */ | ||
133 | ); | ||
134 | |||
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 */ | ||
142 | void silk_ana_filt_bank_1( | ||
143 | const opus_int16 *in, /* I Input signal [N] */ | ||
144 | opus_int32 *S, /* I/O State vector [2] */ | ||
145 | opus_int16 *outL, /* O Low band [N/2] */ | ||
146 | opus_int16 *outH, /* O High band [N/2] */ | ||
147 | const opus_int32 N /* I Number of input samples */ | ||
148 | ); | ||
149 | |||
150 | /********************************************************************/ | ||
151 | /* SCALAR FUNCTIONS */ | ||
152 | /********************************************************************/ | ||
153 | |||
154 | /* Approximation of 128 * log2() (exact inverse of approx 2^() below) */ | ||
155 | /* Convert input to a log scale */ | ||
156 | opus_int32 silk_lin2log( | ||
157 | const opus_int32 inLin /* I input in linear scale */ | ||
158 | ); | ||
159 | |||
160 | /* Approximation of a sigmoid function */ | ||
161 | opus_int silk_sigm_Q15( | ||
162 | opus_int in_Q5 /* I */ | ||
163 | ); | ||
164 | |||
165 | /* Approximation of 2^() (exact inverse of approx log2() above) */ | ||
166 | /* Convert input to a linear scale */ | ||
167 | opus_int32 silk_log2lin( | ||
168 | const opus_int32 inLog_Q7 /* I input on log scale */ | ||
169 | ); | ||
170 | |||
171 | /* Function that returns the maximum absolut value of the input vector */ | ||
172 | opus_int16 silk_int16_array_maxabs( /* O Maximum absolute value, max: 2^15-1 */ | ||
173 | const opus_int16 *vec, /* I Input vector [len] */ | ||
174 | const opus_int32 len /* I Length of input vector */ | ||
175 | ); | ||
176 | |||
177 | /* Compute number of bits to right shift the sum of squares of a vector */ | ||
178 | /* of int16s to make it fit in an int32 */ | ||
179 | void silk_sum_sqr_shift( | ||
180 | opus_int32 *energy, /* O Energy of x, after shifting to the right */ | ||
181 | opus_int *shift, /* O Number of bits right shift applied to energy */ | ||
182 | const opus_int16 *x, /* I Input vector */ | ||
183 | opus_int len /* I Length of input vector */ | ||
184 | ); | ||
185 | |||
186 | /* Calculates the reflection coefficients from the correlation sequence */ | ||
187 | /* Faster than schur64(), but much less accurate. */ | ||
188 | /* uses SMLAWB(), requiring armv5E and higher. */ | ||
189 | opus_int32 silk_schur( /* O Returns residual energy */ | ||
190 | opus_int16 *rc_Q15, /* O reflection coefficients [order] Q15 */ | ||
191 | const opus_int32 *c, /* I correlations [order+1] */ | ||
192 | const opus_int32 order /* I prediction order */ | ||
193 | ); | ||
194 | |||
195 | /* Calculates the reflection coefficients from the correlation sequence */ | ||
196 | /* Slower than schur(), but more accurate. */ | ||
197 | /* Uses SMULL(), available on armv4 */ | ||
198 | opus_int32 silk_schur64( /* O returns residual energy */ | ||
199 | opus_int32 rc_Q16[], /* O Reflection coefficients [order] Q16 */ | ||
200 | const opus_int32 c[], /* I Correlations [order+1] */ | ||
201 | opus_int32 order /* I Prediction order */ | ||
202 | ); | ||
203 | |||
204 | /* Step up function, converts reflection coefficients to prediction coefficients */ | ||
205 | void silk_k2a( | ||
206 | opus_int32 *A_Q24, /* O Prediction coefficients [order] Q24 */ | ||
207 | const opus_int16 *rc_Q15, /* I Reflection coefficients [order] Q15 */ | ||
208 | const opus_int32 order /* I Prediction order */ | ||
209 | ); | ||
210 | |||
211 | /* Step up function, converts reflection coefficients to prediction coefficients */ | ||
212 | void silk_k2a_Q16( | ||
213 | opus_int32 *A_Q24, /* O Prediction coefficients [order] Q24 */ | ||
214 | const opus_int32 *rc_Q16, /* I Reflection coefficients [order] Q16 */ | ||
215 | const opus_int32 order /* I Prediction order */ | ||
216 | ); | ||
217 | |||
218 | /* Apply sine window to signal vector. */ | ||
219 | /* Window types: */ | ||
220 | /* 1 -> sine window from 0 to pi/2 */ | ||
221 | /* 2 -> sine window from pi/2 to pi */ | ||
222 | /* every other sample of window is linearly interpolated, for speed */ | ||
223 | void silk_apply_sine_window( | ||
224 | opus_int16 px_win[], /* O Pointer to windowed signal */ | ||
225 | const opus_int16 px[], /* I Pointer to input signal */ | ||
226 | const opus_int win_type, /* I Selects a window type */ | ||
227 | const opus_int length /* I Window length, multiple of 4 */ | ||
228 | ); | ||
229 | |||
230 | /* Compute autocorrelation */ | ||
231 | void silk_autocorr( | ||
232 | opus_int32 *results, /* O Result (length correlationCount) */ | ||
233 | opus_int *scale, /* O Scaling of the correlation vector */ | ||
234 | const opus_int16 *inputData, /* I Input data to correlate */ | ||
235 | const opus_int inputDataSize, /* I Length of input */ | ||
236 | const opus_int correlationCount /* I Number of correlation taps to compute */ | ||
237 | ); | ||
238 | |||
239 | void silk_decode_pitch( | ||
240 | opus_int16 lagIndex, /* I */ | ||
241 | opus_int8 contourIndex, /* O */ | ||
242 | opus_int pitch_lags[], /* O 4 pitch values */ | ||
243 | const opus_int Fs_kHz, /* I sampling frequency (kHz) */ | ||
244 | const opus_int nb_subfr /* I number of sub frames */ | ||
245 | ); | ||
246 | |||
247 | opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0 voiced, 1 unvoiced */ | ||
248 | const opus_int16 *frame, /* I Signal of length PE_FRAME_LENGTH_MS*Fs_kHz */ | ||
249 | opus_int *pitch_out, /* O 4 pitch lag values */ | ||
250 | opus_int16 *lagIndex, /* O Lag Index */ | ||
251 | opus_int8 *contourIndex, /* O Pitch contour Index */ | ||
252 | opus_int *LTPCorr_Q15, /* I/O Normalized correlation; input: value from previous frame */ | ||
253 | opus_int prevLag, /* I Last lag of previous frame; set to zero is unvoiced */ | ||
254 | const opus_int32 search_thres1_Q16, /* I First stage threshold for lag candidates 0 - 1 */ | ||
255 | const opus_int search_thres2_Q15, /* I Final threshold for lag candidates 0 - 1 */ | ||
256 | const opus_int Fs_kHz, /* I Sample frequency (kHz) */ | ||
257 | const opus_int complexity, /* I Complexity setting, 0-2, where 2 is highest */ | ||
258 | const opus_int nb_subfr /* I number of 5 ms subframes */ | ||
259 | ); | ||
260 | |||
261 | /* Compute Normalized Line Spectral Frequencies (NLSFs) from whitening filter coefficients */ | ||
262 | /* If not all roots are found, the a_Q16 coefficients are bandwidth expanded until convergence. */ | ||
263 | void silk_A2NLSF( | ||
264 | opus_int16 *NLSF, /* O Normalized Line Spectral Frequencies in Q15 (0..2^15-1) [d] */ | ||
265 | opus_int32 *a_Q16, /* I/O Monic whitening filter coefficients in Q16 [d] */ | ||
266 | const opus_int d /* I Filter order (must be even) */ | ||
267 | ); | ||
268 | |||
269 | /* compute whitening filter coefficients from normalized line spectral frequencies */ | ||
270 | void silk_NLSF2A( | ||
271 | opus_int16 *a_Q12, /* O monic whitening filter coefficients in Q12, [ d ] */ | ||
272 | const opus_int16 *NLSF, /* I normalized line spectral frequencies in Q15, [ d ] */ | ||
273 | const opus_int d /* I filter order (should be even) */ | ||
274 | ); | ||
275 | |||
276 | void silk_insertion_sort_increasing( | ||
277 | opus_int32 *a, /* I/O Unsorted / Sorted vector */ | ||
278 | opus_int *idx, /* O Index vector for the sorted elements */ | ||
279 | const opus_int L, /* I Vector length */ | ||
280 | const opus_int K /* I Number of correctly sorted positions */ | ||
281 | ); | ||
282 | |||
283 | void silk_insertion_sort_decreasing_int16( | ||
284 | opus_int16 *a, /* I/O Unsorted / Sorted vector */ | ||
285 | opus_int *idx, /* O Index vector for the sorted elements */ | ||
286 | const opus_int L, /* I Vector length */ | ||
287 | const opus_int K /* I Number of correctly sorted positions */ | ||
288 | ); | ||
289 | |||
290 | void silk_insertion_sort_increasing_all_values_int16( | ||
291 | opus_int16 *a, /* I/O Unsorted / Sorted vector */ | ||
292 | const opus_int L /* I Vector length */ | ||
293 | ); | ||
294 | |||
295 | /* NLSF stabilizer, for a single input data vector */ | ||
296 | void silk_NLSF_stabilize( | ||
297 | opus_int16 *NLSF_Q15, /* I/O Unstable/stabilized normalized LSF vector in Q15 [L] */ | ||
298 | const opus_int16 *NDeltaMin_Q15, /* I Min distance vector, NDeltaMin_Q15[L] must be >= 1 [L+1] */ | ||
299 | const opus_int L /* I Number of NLSF parameters in the input vector */ | ||
300 | ); | ||
301 | |||
302 | /* Laroia low complexity NLSF weights */ | ||
303 | void silk_NLSF_VQ_weights_laroia( | ||
304 | opus_int16 *pNLSFW_Q_OUT, /* O Pointer to input vector weights [D] */ | ||
305 | const opus_int16 *pNLSF_Q15, /* I Pointer to input vector [D] */ | ||
306 | const opus_int D /* I Input vector dimension (even) */ | ||
307 | ); | ||
308 | |||
309 | /* Compute reflection coefficients from input signal */ | ||
310 | void silk_burg_modified( | ||
311 | opus_int32 *res_nrg, /* O Residual energy */ | ||
312 | opus_int *res_nrg_Q, /* O Residual energy Q value */ | ||
313 | opus_int32 A_Q16[], /* O Prediction coefficients (length order) */ | ||
314 | const opus_int16 x[], /* I Input signal, length: nb_subfr * ( D + subfr_length ) */ | ||
315 | const opus_int32 minInvGain_Q30, /* I Inverse of max prediction gain */ | ||
316 | const opus_int subfr_length, /* I Input signal subframe length (incl. D preceeding samples) */ | ||
317 | const opus_int nb_subfr, /* I Number of subframes stacked in x */ | ||
318 | const opus_int D /* I Order */ | ||
319 | ); | ||
320 | |||
321 | /* Copy and multiply a vector by a constant */ | ||
322 | void silk_scale_copy_vector16( | ||
323 | opus_int16 *data_out, | ||
324 | const opus_int16 *data_in, | ||
325 | opus_int32 gain_Q16, /* I Gain in Q16 */ | ||
326 | const opus_int dataSize /* I Length */ | ||
327 | ); | ||
328 | |||
329 | /* Some for the LTP related function requires Q26 to work.*/ | ||
330 | void silk_scale_vector32_Q26_lshift_18( | ||
331 | opus_int32 *data1, /* I/O Q0/Q18 */ | ||
332 | opus_int32 gain_Q26, /* I Q26 */ | ||
333 | opus_int dataSize /* I length */ | ||
334 | ); | ||
335 | |||
336 | /********************************************************************/ | ||
337 | /* INLINE ARM MATH */ | ||
338 | /********************************************************************/ | ||
339 | |||
340 | /* return sum( inVec1[i] * inVec2[i] ) */ | ||
341 | opus_int32 silk_inner_prod_aligned( | ||
342 | const opus_int16 *const inVec1, /* I input vector 1 */ | ||
343 | const opus_int16 *const inVec2, /* I input vector 2 */ | ||
344 | const opus_int len /* I vector lengths */ | ||
345 | ); | ||
346 | |||
347 | opus_int32 silk_inner_prod_aligned_scale( | ||
348 | const opus_int16 *const inVec1, /* I input vector 1 */ | ||
349 | const opus_int16 *const inVec2, /* I input vector 2 */ | ||
350 | const opus_int scale, /* I number of bits to shift */ | ||
351 | const opus_int len /* I vector lengths */ | ||
352 | ); | ||
353 | |||
354 | opus_int64 silk_inner_prod16_aligned_64( | ||
355 | const opus_int16 *inVec1, /* I input vector 1 */ | ||
356 | const opus_int16 *inVec2, /* I input vector 2 */ | ||
357 | const opus_int len /* I vector lengths */ | ||
358 | ); | ||
359 | |||
360 | /********************************************************************/ | ||
361 | /* MACROS */ | ||
362 | /********************************************************************/ | ||
363 | |||
364 | /* Rotate a32 right by 'rot' bits. Negative rot values result in rotating | ||
365 | left. Output is 32bit int. | ||
366 | Note: contemporary compilers recognize the C expression below and | ||
367 | compile it into a 'ror' instruction if available. No need for inline ASM! */ | ||
368 | static inline opus_int32 silk_ROR32( opus_int32 a32, opus_int rot ) | ||
369 | { | ||
370 | opus_uint32 x = (opus_uint32) a32; | ||
371 | opus_uint32 r = (opus_uint32) rot; | ||
372 | opus_uint32 m = (opus_uint32) -rot; | ||
373 | if( rot == 0 ) { | ||
374 | return a32; | ||
375 | } else if( rot < 0 ) { | ||
376 | return (opus_int32) ((x << m) | (x >> (32 - m))); | ||
377 | } else { | ||
378 | return (opus_int32) ((x << (32 - r)) | (x >> r)); | ||
379 | } | ||
380 | } | ||
381 | |||
382 | /* Allocate opus_int16 alligned to 4-byte memory address */ | ||
383 | #if EMBEDDED_ARM | ||
384 | #define silk_DWORD_ALIGN __attribute__((aligned(4))) | ||
385 | #else | ||
386 | #define silk_DWORD_ALIGN | ||
387 | #endif | ||
388 | |||
389 | /* Useful Macros that can be adjusted to other platforms */ | ||
390 | #define silk_memcpy(dest, src, size) memcpy((dest), (src), (size)) | ||
391 | #define silk_memset(dest, src, size) memset((dest), (src), (size)) | ||
392 | #define silk_memmove(dest, src, size) memmove((dest), (src), (size)) | ||
393 | |||
394 | /* Fixed point macros */ | ||
395 | |||
396 | /* (a32 * b32) output have to be 32bit int */ | ||
397 | #define silk_MUL(a32, b32) ((a32) * (b32)) | ||
398 | |||
399 | /* (a32 * b32) output have to be 32bit uint */ | ||
400 | #define silk_MUL_uint(a32, b32) silk_MUL(a32, b32) | ||
401 | |||
402 | /* a32 + (b32 * c32) output have to be 32bit int */ | ||
403 | #define silk_MLA(a32, b32, c32) silk_ADD32((a32),((b32) * (c32))) | ||
404 | |||
405 | /* a32 + (b32 * c32) output have to be 32bit uint */ | ||
406 | #define silk_MLA_uint(a32, b32, c32) silk_MLA(a32, b32, c32) | ||
407 | |||
408 | /* ((a32 >> 16) * (b32 >> 16)) output have to be 32bit int */ | ||
409 | #define silk_SMULTT(a32, b32) (((a32) >> 16) * ((b32) >> 16)) | ||
410 | |||
411 | /* a32 + ((a32 >> 16) * (b32 >> 16)) output have to be 32bit int */ | ||
412 | #define silk_SMLATT(a32, b32, c32) silk_ADD32((a32),((b32) >> 16) * ((c32) >> 16)) | ||
413 | |||
414 | #define silk_SMLALBB(a64, b16, c16) silk_ADD64((a64),(opus_int64)((opus_int32)(b16) * (opus_int32)(c16))) | ||
415 | |||
416 | /* (a32 * b32) */ | ||
417 | #define silk_SMULL(a32, b32) ((opus_int64)(a32) * /*(opus_int64)*/(b32)) | ||
418 | |||
419 | /* Adds two signed 32-bit values in a way that can overflow, while not relying on undefined behaviour | ||
420 | (just standard two's complement implementation-specific behaviour) */ | ||
421 | #define silk_ADD32_ovflw(a, b) ((opus_int32)((opus_uint32)(a) + (opus_uint32)(b))) | ||
422 | /* Subtractss two signed 32-bit values in a way that can overflow, while not relying on undefined behaviour | ||
423 | (just standard two's complement implementation-specific behaviour) */ | ||
424 | #define silk_SUB32_ovflw(a, b) ((opus_int32)((opus_uint32)(a) - (opus_uint32)(b))) | ||
425 | |||
426 | /* Multiply-accumulate macros that allow overflow in the addition (ie, no asserts in debug mode) */ | ||
427 | #define silk_MLA_ovflw(a32, b32, c32) silk_ADD32_ovflw((a32), (opus_uint32)(b32) * (opus_uint32)(c32)) | ||
428 | #define silk_SMLABB_ovflw(a32, b32, c32) (silk_ADD32_ovflw((a32) , ((opus_int32)((opus_int16)(b32))) * (opus_int32)((opus_int16)(c32)))) | ||
429 | |||
430 | #define silk_DIV32_16(a32, b16) ((opus_int32)((a32) / (b16))) | ||
431 | #define silk_DIV32(a32, b32) ((opus_int32)((a32) / (b32))) | ||
432 | |||
433 | /* These macros enables checking for overflow in silk_API_Debug.h*/ | ||
434 | #define silk_ADD16(a, b) ((a) + (b)) | ||
435 | #define silk_ADD32(a, b) ((a) + (b)) | ||
436 | #define silk_ADD64(a, b) ((a) + (b)) | ||
437 | |||
438 | #define silk_SUB16(a, b) ((a) - (b)) | ||
439 | #define silk_SUB32(a, b) ((a) - (b)) | ||
440 | #define silk_SUB64(a, b) ((a) - (b)) | ||
441 | |||
442 | #define silk_SAT8(a) ((a) > silk_int8_MAX ? silk_int8_MAX : \ | ||
443 | ((a) < silk_int8_MIN ? silk_int8_MIN : (a))) | ||
444 | #define silk_SAT16(a) ((a) > silk_int16_MAX ? silk_int16_MAX : \ | ||
445 | ((a) < silk_int16_MIN ? silk_int16_MIN : (a))) | ||
446 | #define silk_SAT32(a) ((a) > silk_int32_MAX ? silk_int32_MAX : \ | ||
447 | ((a) < silk_int32_MIN ? silk_int32_MIN : (a))) | ||
448 | |||
449 | #define silk_CHECK_FIT8(a) (a) | ||
450 | #define silk_CHECK_FIT16(a) (a) | ||
451 | #define silk_CHECK_FIT32(a) (a) | ||
452 | |||
453 | #define silk_ADD_SAT16(a, b) (opus_int16)silk_SAT16( silk_ADD32( (opus_int32)(a), (b) ) ) | ||
454 | #define silk_ADD_SAT64(a, b) ((((a) + (b)) & 0x8000000000000000LL) == 0 ? \ | ||
455 | ((((a) & (b)) & 0x8000000000000000LL) != 0 ? silk_int64_MIN : (a)+(b)) : \ | ||
456 | ((((a) | (b)) & 0x8000000000000000LL) == 0 ? silk_int64_MAX : (a)+(b)) ) | ||
457 | |||
458 | #define silk_SUB_SAT16(a, b) (opus_int16)silk_SAT16( silk_SUB32( (opus_int32)(a), (b) ) ) | ||
459 | #define silk_SUB_SAT64(a, b) ((((a)-(b)) & 0x8000000000000000LL) == 0 ? \ | ||
460 | (( (a) & ((b)^0x8000000000000000LL) & 0x8000000000000000LL) ? silk_int64_MIN : (a)-(b)) : \ | ||
461 | ((((a)^0x8000000000000000LL) & (b) & 0x8000000000000000LL) ? silk_int64_MAX : (a)-(b)) ) | ||
462 | |||
463 | /* Saturation for positive input values */ | ||
464 | #define silk_POS_SAT32(a) ((a) > silk_int32_MAX ? silk_int32_MAX : (a)) | ||
465 | |||
466 | /* Add with saturation for positive input values */ | ||
467 | #define silk_ADD_POS_SAT8(a, b) ((((a)+(b)) & 0x80) ? silk_int8_MAX : ((a)+(b))) | ||
468 | #define silk_ADD_POS_SAT16(a, b) ((((a)+(b)) & 0x8000) ? silk_int16_MAX : ((a)+(b))) | ||
469 | #define silk_ADD_POS_SAT32(a, b) ((((a)+(b)) & 0x80000000) ? silk_int32_MAX : ((a)+(b))) | ||
470 | #define silk_ADD_POS_SAT64(a, b) ((((a)+(b)) & 0x8000000000000000LL) ? silk_int64_MAX : ((a)+(b))) | ||
471 | |||
472 | #define silk_LSHIFT8(a, shift) ((opus_int8)((opus_uint8)(a)<<(shift))) /* shift >= 0, shift < 8 */ | ||
473 | #define silk_LSHIFT16(a, shift) ((opus_int16)((opus_uint16)(a)<<(shift))) /* shift >= 0, shift < 16 */ | ||
474 | #define silk_LSHIFT32(a, shift) ((opus_int32)((opus_uint32)(a)<<(shift))) /* shift >= 0, shift < 32 */ | ||
475 | #define silk_LSHIFT64(a, shift) ((opus_int64)((opus_uint64)(a)<<(shift))) /* shift >= 0, shift < 64 */ | ||
476 | #define silk_LSHIFT(a, shift) silk_LSHIFT32(a, shift) /* shift >= 0, shift < 32 */ | ||
477 | |||
478 | #define silk_RSHIFT8(a, shift) ((a)>>(shift)) /* shift >= 0, shift < 8 */ | ||
479 | #define silk_RSHIFT16(a, shift) ((a)>>(shift)) /* shift >= 0, shift < 16 */ | ||
480 | #define silk_RSHIFT32(a, shift) ((a)>>(shift)) /* shift >= 0, shift < 32 */ | ||
481 | #define silk_RSHIFT64(a, shift) ((a)>>(shift)) /* shift >= 0, shift < 64 */ | ||
482 | #define silk_RSHIFT(a, shift) silk_RSHIFT32(a, shift) /* shift >= 0, shift < 32 */ | ||
483 | |||
484 | /* saturates before shifting */ | ||
485 | #define silk_LSHIFT_SAT32(a, shift) (silk_LSHIFT32( silk_LIMIT( (a), silk_RSHIFT32( silk_int32_MIN, (shift) ), \ | ||
486 | silk_RSHIFT32( silk_int32_MAX, (shift) ) ), (shift) )) | ||
487 | |||
488 | #define silk_LSHIFT_ovflw(a, shift) ((opus_int32)((opus_uint32)(a) << (shift))) /* shift >= 0, allowed to overflow */ | ||
489 | #define silk_LSHIFT_uint(a, shift) ((a) << (shift)) /* shift >= 0 */ | ||
490 | #define silk_RSHIFT_uint(a, shift) ((a) >> (shift)) /* shift >= 0 */ | ||
491 | |||
492 | #define silk_ADD_LSHIFT(a, b, shift) ((a) + silk_LSHIFT((b), (shift))) /* shift >= 0 */ | ||
493 | #define silk_ADD_LSHIFT32(a, b, shift) silk_ADD32((a), silk_LSHIFT32((b), (shift))) /* shift >= 0 */ | ||
494 | #define silk_ADD_LSHIFT_uint(a, b, shift) ((a) + silk_LSHIFT_uint((b), (shift))) /* shift >= 0 */ | ||
495 | #define silk_ADD_RSHIFT(a, b, shift) ((a) + silk_RSHIFT((b), (shift))) /* shift >= 0 */ | ||
496 | #define silk_ADD_RSHIFT32(a, b, shift) silk_ADD32((a), silk_RSHIFT32((b), (shift))) /* shift >= 0 */ | ||
497 | #define silk_ADD_RSHIFT_uint(a, b, shift) ((a) + silk_RSHIFT_uint((b), (shift))) /* shift >= 0 */ | ||
498 | #define silk_SUB_LSHIFT32(a, b, shift) silk_SUB32((a), silk_LSHIFT32((b), (shift))) /* shift >= 0 */ | ||
499 | #define silk_SUB_RSHIFT32(a, b, shift) silk_SUB32((a), silk_RSHIFT32((b), (shift))) /* shift >= 0 */ | ||
500 | |||
501 | /* Requires that shift > 0 */ | ||
502 | #define silk_RSHIFT_ROUND(a, shift) ((shift) == 1 ? ((a) >> 1) + ((a) & 1) : (((a) >> ((shift) - 1)) + 1) >> 1) | ||
503 | #define silk_RSHIFT_ROUND64(a, shift) ((shift) == 1 ? ((a) >> 1) + ((a) & 1) : (((a) >> ((shift) - 1)) + 1) >> 1) | ||
504 | |||
505 | /* Number of rightshift required to fit the multiplication */ | ||
506 | #define silk_NSHIFT_MUL_32_32(a, b) ( -(31- (32-silk_CLZ32(silk_abs(a)) + (32-silk_CLZ32(silk_abs(b))))) ) | ||
507 | #define silk_NSHIFT_MUL_16_16(a, b) ( -(15- (16-silk_CLZ16(silk_abs(a)) + (16-silk_CLZ16(silk_abs(b))))) ) | ||
508 | |||
509 | |||
510 | #define silk_min(a, b) (((a) < (b)) ? (a) : (b)) | ||
511 | #define silk_max(a, b) (((a) > (b)) ? (a) : (b)) | ||
512 | |||
513 | /* Macro to convert floating-point constants to fixed-point */ | ||
514 | #define SILK_FIX_CONST( C, Q ) ((opus_int32)((C) * ((opus_int64)1 << (Q)) + 0.5)) | ||
515 | |||
516 | /* silk_min() versions with typecast in the function call */ | ||
517 | static inline opus_int silk_min_int(opus_int a, opus_int b) | ||
518 | { | ||
519 | return (((a) < (b)) ? (a) : (b)); | ||
520 | } | ||
521 | static inline opus_int16 silk_min_16(opus_int16 a, opus_int16 b) | ||
522 | { | ||
523 | return (((a) < (b)) ? (a) : (b)); | ||
524 | } | ||
525 | static inline opus_int32 silk_min_32(opus_int32 a, opus_int32 b) | ||
526 | { | ||
527 | return (((a) < (b)) ? (a) : (b)); | ||
528 | } | ||
529 | static inline opus_int64 silk_min_64(opus_int64 a, opus_int64 b) | ||
530 | { | ||
531 | return (((a) < (b)) ? (a) : (b)); | ||
532 | } | ||
533 | |||
534 | /* silk_min() versions with typecast in the function call */ | ||
535 | static inline opus_int silk_max_int(opus_int a, opus_int b) | ||
536 | { | ||
537 | return (((a) > (b)) ? (a) : (b)); | ||
538 | } | ||
539 | static inline opus_int16 silk_max_16(opus_int16 a, opus_int16 b) | ||
540 | { | ||
541 | return (((a) > (b)) ? (a) : (b)); | ||
542 | } | ||
543 | static inline opus_int32 silk_max_32(opus_int32 a, opus_int32 b) | ||
544 | { | ||
545 | return (((a) > (b)) ? (a) : (b)); | ||
546 | } | ||
547 | static inline opus_int64 silk_max_64(opus_int64 a, opus_int64 b) | ||
548 | { | ||
549 | return (((a) > (b)) ? (a) : (b)); | ||
550 | } | ||
551 | |||
552 | #define silk_LIMIT( a, limit1, limit2) ((limit1) > (limit2) ? ((a) > (limit1) ? (limit1) : ((a) < (limit2) ? (limit2) : (a))) \ | ||
553 | : ((a) > (limit2) ? (limit2) : ((a) < (limit1) ? (limit1) : (a)))) | ||
554 | |||
555 | #define silk_LIMIT_int silk_LIMIT | ||
556 | #define silk_LIMIT_16 silk_LIMIT | ||
557 | #define silk_LIMIT_32 silk_LIMIT | ||
558 | |||
559 | #define silk_abs(a) (((a) > 0) ? (a) : -(a)) /* Be careful, silk_abs returns wrong when input equals to silk_intXX_MIN */ | ||
560 | #define silk_abs_int(a) (((a) ^ ((a) >> (8 * sizeof(a) - 1))) - ((a) >> (8 * sizeof(a) - 1))) | ||
561 | #define silk_abs_int32(a) (((a) ^ ((a) >> 31)) - ((a) >> 31)) | ||
562 | #define silk_abs_int64(a) (((a) > 0) ? (a) : -(a)) | ||
563 | |||
564 | #define silk_sign(a) ((a) > 0 ? 1 : ( (a) < 0 ? -1 : 0 )) | ||
565 | |||
566 | /* PSEUDO-RANDOM GENERATOR */ | ||
567 | /* Make sure to store the result as the seed for the next call (also in between */ | ||
568 | /* frames), otherwise result won't be random at all. When only using some of the */ | ||
569 | /* bits, take the most significant bits by right-shifting. */ | ||
570 | #define silk_RAND(seed) (silk_MLA_ovflw(907633515, (seed), 196314165)) | ||
571 | |||
572 | /* Add some multiplication functions that can be easily mapped to ARM. */ | ||
573 | |||
574 | /* silk_SMMUL: Signed top word multiply. | ||
575 | ARMv6 2 instruction cycles. | ||
576 | ARMv3M+ 3 instruction cycles. use SMULL and ignore LSB registers.(except xM)*/ | ||
577 | /*#define silk_SMMUL(a32, b32) (opus_int32)silk_RSHIFT(silk_SMLAL(silk_SMULWB((a32), (b32)), (a32), silk_RSHIFT_ROUND((b32), 16)), 16)*/ | ||
578 | /* the following seems faster on x86 */ | ||
579 | #define silk_SMMUL(a32, b32) (opus_int32)silk_RSHIFT64(silk_SMULL((a32), (b32)), 32) | ||
580 | |||
581 | #include "Inlines.h" | ||
582 | #include "MacroCount.h" | ||
583 | #include "MacroDebug.h" | ||
584 | |||
585 | #ifdef __cplusplus | ||
586 | } | ||
587 | #endif | ||
588 | |||
589 | #endif /* SILK_SIGPROC_FIX_H */ | ||