|
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 /* Compute number of bits to right shift the sum of squares of a vector */ |
|
172 /* of int16s to make it fit in an int32 */ |
|
173 void silk_sum_sqr_shift( |
|
174 opus_int32 *energy, /* O Energy of x, after shifting to the right */ |
|
175 opus_int *shift, /* O Number of bits right shift applied to energy */ |
|
176 const opus_int16 *x, /* I Input vector */ |
|
177 opus_int len /* I Length of input vector */ |
|
178 ); |
|
179 |
|
180 /* Calculates the reflection coefficients from the correlation sequence */ |
|
181 /* Faster than schur64(), but much less accurate. */ |
|
182 /* uses SMLAWB(), requiring armv5E and higher. */ |
|
183 opus_int32 silk_schur( /* O Returns residual energy */ |
|
184 opus_int16 *rc_Q15, /* O reflection coefficients [order] Q15 */ |
|
185 const opus_int32 *c, /* I correlations [order+1] */ |
|
186 const opus_int32 order /* I prediction order */ |
|
187 ); |
|
188 |
|
189 /* Calculates the reflection coefficients from the correlation sequence */ |
|
190 /* Slower than schur(), but more accurate. */ |
|
191 /* Uses SMULL(), available on armv4 */ |
|
192 opus_int32 silk_schur64( /* O returns residual energy */ |
|
193 opus_int32 rc_Q16[], /* O Reflection coefficients [order] Q16 */ |
|
194 const opus_int32 c[], /* I Correlations [order+1] */ |
|
195 opus_int32 order /* I Prediction order */ |
|
196 ); |
|
197 |
|
198 /* Step up function, converts reflection coefficients to prediction coefficients */ |
|
199 void silk_k2a( |
|
200 opus_int32 *A_Q24, /* O Prediction coefficients [order] Q24 */ |
|
201 const opus_int16 *rc_Q15, /* I Reflection coefficients [order] Q15 */ |
|
202 const opus_int32 order /* I Prediction order */ |
|
203 ); |
|
204 |
|
205 /* Step up function, converts reflection coefficients to prediction coefficients */ |
|
206 void silk_k2a_Q16( |
|
207 opus_int32 *A_Q24, /* O Prediction coefficients [order] Q24 */ |
|
208 const opus_int32 *rc_Q16, /* I Reflection coefficients [order] Q16 */ |
|
209 const opus_int32 order /* I Prediction order */ |
|
210 ); |
|
211 |
|
212 /* Apply sine window to signal vector. */ |
|
213 /* Window types: */ |
|
214 /* 1 -> sine window from 0 to pi/2 */ |
|
215 /* 2 -> sine window from pi/2 to pi */ |
|
216 /* every other sample of window is linearly interpolated, for speed */ |
|
217 void silk_apply_sine_window( |
|
218 opus_int16 px_win[], /* O Pointer to windowed signal */ |
|
219 const opus_int16 px[], /* I Pointer to input signal */ |
|
220 const opus_int win_type, /* I Selects a window type */ |
|
221 const opus_int length /* I Window length, multiple of 4 */ |
|
222 ); |
|
223 |
|
224 /* Compute autocorrelation */ |
|
225 void silk_autocorr( |
|
226 opus_int32 *results, /* O Result (length correlationCount) */ |
|
227 opus_int *scale, /* O Scaling of the correlation vector */ |
|
228 const opus_int16 *inputData, /* I Input data to correlate */ |
|
229 const opus_int inputDataSize, /* I Length of input */ |
|
230 const opus_int correlationCount, /* I Number of correlation taps to compute */ |
|
231 int arch /* I Run-time architecture */ |
|
232 ); |
|
233 |
|
234 void silk_decode_pitch( |
|
235 opus_int16 lagIndex, /* I */ |
|
236 opus_int8 contourIndex, /* O */ |
|
237 opus_int pitch_lags[], /* O 4 pitch values */ |
|
238 const opus_int Fs_kHz, /* I sampling frequency (kHz) */ |
|
239 const opus_int nb_subfr /* I number of sub frames */ |
|
240 ); |
|
241 |
|
242 opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0 voiced, 1 unvoiced */ |
|
243 const opus_int16 *frame, /* I Signal of length PE_FRAME_LENGTH_MS*Fs_kHz */ |
|
244 opus_int *pitch_out, /* O 4 pitch lag values */ |
|
245 opus_int16 *lagIndex, /* O Lag Index */ |
|
246 opus_int8 *contourIndex, /* O Pitch contour Index */ |
|
247 opus_int *LTPCorr_Q15, /* I/O Normalized correlation; input: value from previous frame */ |
|
248 opus_int prevLag, /* I Last lag of previous frame; set to zero is unvoiced */ |
|
249 const opus_int32 search_thres1_Q16, /* I First stage threshold for lag candidates 0 - 1 */ |
|
250 const opus_int search_thres2_Q13, /* I Final threshold for lag candidates 0 - 1 */ |
|
251 const opus_int Fs_kHz, /* I Sample frequency (kHz) */ |
|
252 const opus_int complexity, /* I Complexity setting, 0-2, where 2 is highest */ |
|
253 const opus_int nb_subfr, /* I number of 5 ms subframes */ |
|
254 int arch /* I Run-time architecture */ |
|
255 ); |
|
256 |
|
257 /* Compute Normalized Line Spectral Frequencies (NLSFs) from whitening filter coefficients */ |
|
258 /* If not all roots are found, the a_Q16 coefficients are bandwidth expanded until convergence. */ |
|
259 void silk_A2NLSF( |
|
260 opus_int16 *NLSF, /* O Normalized Line Spectral Frequencies in Q15 (0..2^15-1) [d] */ |
|
261 opus_int32 *a_Q16, /* I/O Monic whitening filter coefficients in Q16 [d] */ |
|
262 const opus_int d /* I Filter order (must be even) */ |
|
263 ); |
|
264 |
|
265 /* compute whitening filter coefficients from normalized line spectral frequencies */ |
|
266 void silk_NLSF2A( |
|
267 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 ] */ |
|
269 const opus_int d /* I filter order (should be even) */ |
|
270 ); |
|
271 |
|
272 void silk_insertion_sort_increasing( |
|
273 opus_int32 *a, /* I/O Unsorted / Sorted vector */ |
|
274 opus_int *idx, /* O Index vector for the sorted elements */ |
|
275 const opus_int L, /* I Vector length */ |
|
276 const opus_int K /* I Number of correctly sorted positions */ |
|
277 ); |
|
278 |
|
279 void silk_insertion_sort_decreasing_int16( |
|
280 opus_int16 *a, /* I/O Unsorted / Sorted vector */ |
|
281 opus_int *idx, /* O Index vector for the sorted elements */ |
|
282 const opus_int L, /* I Vector length */ |
|
283 const opus_int K /* I Number of correctly sorted positions */ |
|
284 ); |
|
285 |
|
286 void silk_insertion_sort_increasing_all_values_int16( |
|
287 opus_int16 *a, /* I/O Unsorted / Sorted vector */ |
|
288 const opus_int L /* I Vector length */ |
|
289 ); |
|
290 |
|
291 /* NLSF stabilizer, for a single input data vector */ |
|
292 void silk_NLSF_stabilize( |
|
293 opus_int16 *NLSF_Q15, /* I/O Unstable/stabilized normalized LSF vector in Q15 [L] */ |
|
294 const opus_int16 *NDeltaMin_Q15, /* I Min distance vector, NDeltaMin_Q15[L] must be >= 1 [L+1] */ |
|
295 const opus_int L /* I Number of NLSF parameters in the input vector */ |
|
296 ); |
|
297 |
|
298 /* Laroia low complexity NLSF weights */ |
|
299 void silk_NLSF_VQ_weights_laroia( |
|
300 opus_int16 *pNLSFW_Q_OUT, /* O Pointer to input vector weights [D] */ |
|
301 const opus_int16 *pNLSF_Q15, /* I Pointer to input vector [D] */ |
|
302 const opus_int D /* I Input vector dimension (even) */ |
|
303 ); |
|
304 |
|
305 /* Compute reflection coefficients from input signal */ |
|
306 void silk_burg_modified( |
|
307 opus_int32 *res_nrg, /* O Residual energy */ |
|
308 opus_int *res_nrg_Q, /* O Residual energy Q value */ |
|
309 opus_int32 A_Q16[], /* O Prediction coefficients (length order) */ |
|
310 const opus_int16 x[], /* I Input signal, length: nb_subfr * ( D + subfr_length ) */ |
|
311 const opus_int32 minInvGain_Q30, /* I Inverse of max prediction gain */ |
|
312 const opus_int subfr_length, /* I Input signal subframe length (incl. D preceding samples) */ |
|
313 const opus_int nb_subfr, /* I Number of subframes stacked in x */ |
|
314 const opus_int D, /* I Order */ |
|
315 int arch /* I Run-time architecture */ |
|
316 ); |
|
317 |
|
318 /* Copy and multiply a vector by a constant */ |
|
319 void silk_scale_copy_vector16( |
|
320 opus_int16 *data_out, |
|
321 const opus_int16 *data_in, |
|
322 opus_int32 gain_Q16, /* I Gain in Q16 */ |
|
323 const opus_int dataSize /* I Length */ |
|
324 ); |
|
325 |
|
326 /* Some for the LTP related function requires Q26 to work.*/ |
|
327 void silk_scale_vector32_Q26_lshift_18( |
|
328 opus_int32 *data1, /* I/O Q0/Q18 */ |
|
329 opus_int32 gain_Q26, /* I Q26 */ |
|
330 opus_int dataSize /* I length */ |
|
331 ); |
|
332 |
|
333 /********************************************************************/ |
|
334 /* INLINE ARM MATH */ |
|
335 /********************************************************************/ |
|
336 |
|
337 /* return sum( inVec1[i] * inVec2[i] ) */ |
|
338 opus_int32 silk_inner_prod_aligned( |
|
339 const opus_int16 *const inVec1, /* I input vector 1 */ |
|
340 const opus_int16 *const inVec2, /* I input vector 2 */ |
|
341 const opus_int len /* I vector lengths */ |
|
342 ); |
|
343 |
|
344 opus_int32 silk_inner_prod_aligned_scale( |
|
345 const opus_int16 *const inVec1, /* I input vector 1 */ |
|
346 const opus_int16 *const inVec2, /* I input vector 2 */ |
|
347 const opus_int scale, /* I number of bits to shift */ |
|
348 const opus_int len /* I vector lengths */ |
|
349 ); |
|
350 |
|
351 opus_int64 silk_inner_prod16_aligned_64( |
|
352 const opus_int16 *inVec1, /* I input vector 1 */ |
|
353 const opus_int16 *inVec2, /* I input vector 2 */ |
|
354 const opus_int len /* I vector lengths */ |
|
355 ); |
|
356 |
|
357 /********************************************************************/ |
|
358 /* MACROS */ |
|
359 /********************************************************************/ |
|
360 |
|
361 /* Rotate a32 right by 'rot' bits. Negative rot values result in rotating |
|
362 left. Output is 32bit int. |
|
363 Note: contemporary compilers recognize the C expression below and |
|
364 compile it into a 'ror' instruction if available. No need for OPUS_INLINE ASM! */ |
|
365 static OPUS_INLINE opus_int32 silk_ROR32( opus_int32 a32, opus_int rot ) |
|
366 { |
|
367 opus_uint32 x = (opus_uint32) a32; |
|
368 opus_uint32 r = (opus_uint32) rot; |
|
369 opus_uint32 m = (opus_uint32) -rot; |
|
370 if( rot == 0 ) { |
|
371 return a32; |
|
372 } else if( rot < 0 ) { |
|
373 return (opus_int32) ((x << m) | (x >> (32 - m))); |
|
374 } else { |
|
375 return (opus_int32) ((x << (32 - r)) | (x >> r)); |
|
376 } |
|
377 } |
|
378 |
|
379 /* Allocate opus_int16 aligned to 4-byte memory address */ |
|
380 #if EMBEDDED_ARM |
|
381 #define silk_DWORD_ALIGN __attribute__((aligned(4))) |
|
382 #else |
|
383 #define silk_DWORD_ALIGN |
|
384 #endif |
|
385 |
|
386 /* Useful Macros that can be adjusted to other platforms */ |
|
387 #define silk_memcpy(dest, src, size) memcpy((dest), (src), (size)) |
|
388 #define silk_memset(dest, src, size) memset((dest), (src), (size)) |
|
389 #define silk_memmove(dest, src, size) memmove((dest), (src), (size)) |
|
390 |
|
391 /* Fixed point macros */ |
|
392 |
|
393 /* (a32 * b32) output have to be 32bit int */ |
|
394 #define silk_MUL(a32, b32) ((a32) * (b32)) |
|
395 |
|
396 /* (a32 * b32) output have to be 32bit uint */ |
|
397 #define silk_MUL_uint(a32, b32) silk_MUL(a32, b32) |
|
398 |
|
399 /* a32 + (b32 * c32) output have to be 32bit int */ |
|
400 #define silk_MLA(a32, b32, c32) silk_ADD32((a32),((b32) * (c32))) |
|
401 |
|
402 /* a32 + (b32 * c32) output have to be 32bit uint */ |
|
403 #define silk_MLA_uint(a32, b32, c32) silk_MLA(a32, b32, c32) |
|
404 |
|
405 /* ((a32 >> 16) * (b32 >> 16)) output have to be 32bit int */ |
|
406 #define silk_SMULTT(a32, b32) (((a32) >> 16) * ((b32) >> 16)) |
|
407 |
|
408 /* a32 + ((a32 >> 16) * (b32 >> 16)) output have to be 32bit int */ |
|
409 #define silk_SMLATT(a32, b32, c32) silk_ADD32((a32),((b32) >> 16) * ((c32) >> 16)) |
|
410 |
|
411 #define silk_SMLALBB(a64, b16, c16) silk_ADD64((a64),(opus_int64)((opus_int32)(b16) * (opus_int32)(c16))) |
|
412 |
|
413 /* (a32 * b32) */ |
|
414 #define silk_SMULL(a32, b32) ((opus_int64)(a32) * /*(opus_int64)*/(b32)) |
|
415 |
|
416 /* Adds two signed 32-bit values in a way that can overflow, while not relying on undefined behaviour |
|
417 (just standard two's complement implementation-specific behaviour) */ |
|
418 #define silk_ADD32_ovflw(a, b) ((opus_int32)((opus_uint32)(a) + (opus_uint32)(b))) |
|
419 /* Subtractss 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_SUB32_ovflw(a, b) ((opus_int32)((opus_uint32)(a) - (opus_uint32)(b))) |
|
422 |
|
423 /* Multiply-accumulate macros that allow overflow in the addition (ie, no asserts in debug mode) */ |
|
424 #define silk_MLA_ovflw(a32, b32, c32) silk_ADD32_ovflw((a32), (opus_uint32)(b32) * (opus_uint32)(c32)) |
|
425 #define silk_SMLABB_ovflw(a32, b32, c32) (silk_ADD32_ovflw((a32) , ((opus_int32)((opus_int16)(b32))) * (opus_int32)((opus_int16)(c32)))) |
|
426 |
|
427 #define silk_DIV32_16(a32, b16) ((opus_int32)((a32) / (b16))) |
|
428 #define silk_DIV32(a32, b32) ((opus_int32)((a32) / (b32))) |
|
429 |
|
430 /* These macros enables checking for overflow in silk_API_Debug.h*/ |
|
431 #define silk_ADD16(a, b) ((a) + (b)) |
|
432 #define silk_ADD32(a, b) ((a) + (b)) |
|
433 #define silk_ADD64(a, b) ((a) + (b)) |
|
434 |
|
435 #define silk_SUB16(a, b) ((a) - (b)) |
|
436 #define silk_SUB32(a, b) ((a) - (b)) |
|
437 #define silk_SUB64(a, b) ((a) - (b)) |
|
438 |
|
439 #define silk_SAT8(a) ((a) > silk_int8_MAX ? silk_int8_MAX : \ |
|
440 ((a) < silk_int8_MIN ? silk_int8_MIN : (a))) |
|
441 #define silk_SAT16(a) ((a) > silk_int16_MAX ? silk_int16_MAX : \ |
|
442 ((a) < silk_int16_MIN ? silk_int16_MIN : (a))) |
|
443 #define silk_SAT32(a) ((a) > silk_int32_MAX ? silk_int32_MAX : \ |
|
444 ((a) < silk_int32_MIN ? silk_int32_MIN : (a))) |
|
445 |
|
446 #define silk_CHECK_FIT8(a) (a) |
|
447 #define silk_CHECK_FIT16(a) (a) |
|
448 #define silk_CHECK_FIT32(a) (a) |
|
449 |
|
450 #define silk_ADD_SAT16(a, b) (opus_int16)silk_SAT16( silk_ADD32( (opus_int32)(a), (b) ) ) |
|
451 #define silk_ADD_SAT64(a, b) ((((a) + (b)) & 0x8000000000000000LL) == 0 ? \ |
|
452 ((((a) & (b)) & 0x8000000000000000LL) != 0 ? silk_int64_MIN : (a)+(b)) : \ |
|
453 ((((a) | (b)) & 0x8000000000000000LL) == 0 ? silk_int64_MAX : (a)+(b)) ) |
|
454 |
|
455 #define silk_SUB_SAT16(a, b) (opus_int16)silk_SAT16( silk_SUB32( (opus_int32)(a), (b) ) ) |
|
456 #define silk_SUB_SAT64(a, b) ((((a)-(b)) & 0x8000000000000000LL) == 0 ? \ |
|
457 (( (a) & ((b)^0x8000000000000000LL) & 0x8000000000000000LL) ? silk_int64_MIN : (a)-(b)) : \ |
|
458 ((((a)^0x8000000000000000LL) & (b) & 0x8000000000000000LL) ? silk_int64_MAX : (a)-(b)) ) |
|
459 |
|
460 /* Saturation for positive input values */ |
|
461 #define silk_POS_SAT32(a) ((a) > silk_int32_MAX ? silk_int32_MAX : (a)) |
|
462 |
|
463 /* Add with saturation for positive input values */ |
|
464 #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))) |
|
466 #define silk_ADD_POS_SAT32(a, b) ((((a)+(b)) & 0x80000000) ? silk_int32_MAX : ((a)+(b))) |
|
467 #define silk_ADD_POS_SAT64(a, b) ((((a)+(b)) & 0x8000000000000000LL) ? silk_int64_MAX : ((a)+(b))) |
|
468 |
|
469 #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 */ |
|
471 #define silk_LSHIFT32(a, shift) ((opus_int32)((opus_uint32)(a)<<(shift))) /* shift >= 0, shift < 32 */ |
|
472 #define silk_LSHIFT64(a, shift) ((opus_int64)((opus_uint64)(a)<<(shift))) /* shift >= 0, shift < 64 */ |
|
473 #define silk_LSHIFT(a, shift) silk_LSHIFT32(a, shift) /* shift >= 0, shift < 32 */ |
|
474 |
|
475 #define silk_RSHIFT8(a, shift) ((a)>>(shift)) /* shift >= 0, shift < 8 */ |
|
476 #define silk_RSHIFT16(a, shift) ((a)>>(shift)) /* shift >= 0, shift < 16 */ |
|
477 #define silk_RSHIFT32(a, shift) ((a)>>(shift)) /* shift >= 0, shift < 32 */ |
|
478 #define silk_RSHIFT64(a, shift) ((a)>>(shift)) /* shift >= 0, shift < 64 */ |
|
479 #define silk_RSHIFT(a, shift) silk_RSHIFT32(a, shift) /* shift >= 0, shift < 32 */ |
|
480 |
|
481 /* saturates before shifting */ |
|
482 #define silk_LSHIFT_SAT32(a, shift) (silk_LSHIFT32( silk_LIMIT( (a), silk_RSHIFT32( silk_int32_MIN, (shift) ), \ |
|
483 silk_RSHIFT32( silk_int32_MAX, (shift) ) ), (shift) )) |
|
484 |
|
485 #define silk_LSHIFT_ovflw(a, shift) ((opus_int32)((opus_uint32)(a) << (shift))) /* shift >= 0, allowed to overflow */ |
|
486 #define silk_LSHIFT_uint(a, shift) ((a) << (shift)) /* shift >= 0 */ |
|
487 #define silk_RSHIFT_uint(a, shift) ((a) >> (shift)) /* shift >= 0 */ |
|
488 |
|
489 #define silk_ADD_LSHIFT(a, b, shift) ((a) + silk_LSHIFT((b), (shift))) /* shift >= 0 */ |
|
490 #define silk_ADD_LSHIFT32(a, b, shift) silk_ADD32((a), silk_LSHIFT32((b), (shift))) /* shift >= 0 */ |
|
491 #define silk_ADD_LSHIFT_uint(a, b, shift) ((a) + silk_LSHIFT_uint((b), (shift))) /* shift >= 0 */ |
|
492 #define silk_ADD_RSHIFT(a, b, shift) ((a) + silk_RSHIFT((b), (shift))) /* shift >= 0 */ |
|
493 #define silk_ADD_RSHIFT32(a, b, shift) silk_ADD32((a), silk_RSHIFT32((b), (shift))) /* shift >= 0 */ |
|
494 #define silk_ADD_RSHIFT_uint(a, b, shift) ((a) + silk_RSHIFT_uint((b), (shift))) /* shift >= 0 */ |
|
495 #define silk_SUB_LSHIFT32(a, b, shift) silk_SUB32((a), silk_LSHIFT32((b), (shift))) /* shift >= 0 */ |
|
496 #define silk_SUB_RSHIFT32(a, b, shift) silk_SUB32((a), silk_RSHIFT32((b), (shift))) /* shift >= 0 */ |
|
497 |
|
498 /* Requires that shift > 0 */ |
|
499 #define silk_RSHIFT_ROUND(a, shift) ((shift) == 1 ? ((a) >> 1) + ((a) & 1) : (((a) >> ((shift) - 1)) + 1) >> 1) |
|
500 #define silk_RSHIFT_ROUND64(a, shift) ((shift) == 1 ? ((a) >> 1) + ((a) & 1) : (((a) >> ((shift) - 1)) + 1) >> 1) |
|
501 |
|
502 /* Number of rightshift required to fit the multiplication */ |
|
503 #define silk_NSHIFT_MUL_32_32(a, b) ( -(31- (32-silk_CLZ32(silk_abs(a)) + (32-silk_CLZ32(silk_abs(b))))) ) |
|
504 #define silk_NSHIFT_MUL_16_16(a, b) ( -(15- (16-silk_CLZ16(silk_abs(a)) + (16-silk_CLZ16(silk_abs(b))))) ) |
|
505 |
|
506 |
|
507 #define silk_min(a, b) (((a) < (b)) ? (a) : (b)) |
|
508 #define silk_max(a, b) (((a) > (b)) ? (a) : (b)) |
|
509 |
|
510 /* Macro to convert floating-point constants to fixed-point */ |
|
511 #define SILK_FIX_CONST( C, Q ) ((opus_int32)((C) * ((opus_int64)1 << (Q)) + 0.5)) |
|
512 |
|
513 /* silk_min() versions with typecast in the function call */ |
|
514 static OPUS_INLINE opus_int silk_min_int(opus_int a, opus_int b) |
|
515 { |
|
516 return (((a) < (b)) ? (a) : (b)); |
|
517 } |
|
518 static OPUS_INLINE opus_int16 silk_min_16(opus_int16 a, opus_int16 b) |
|
519 { |
|
520 return (((a) < (b)) ? (a) : (b)); |
|
521 } |
|
522 static OPUS_INLINE opus_int32 silk_min_32(opus_int32 a, opus_int32 b) |
|
523 { |
|
524 return (((a) < (b)) ? (a) : (b)); |
|
525 } |
|
526 static OPUS_INLINE opus_int64 silk_min_64(opus_int64 a, opus_int64 b) |
|
527 { |
|
528 return (((a) < (b)) ? (a) : (b)); |
|
529 } |
|
530 |
|
531 /* silk_min() versions with typecast in the function call */ |
|
532 static OPUS_INLINE opus_int silk_max_int(opus_int a, opus_int b) |
|
533 { |
|
534 return (((a) > (b)) ? (a) : (b)); |
|
535 } |
|
536 static OPUS_INLINE opus_int16 silk_max_16(opus_int16 a, opus_int16 b) |
|
537 { |
|
538 return (((a) > (b)) ? (a) : (b)); |
|
539 } |
|
540 static OPUS_INLINE opus_int32 silk_max_32(opus_int32 a, opus_int32 b) |
|
541 { |
|
542 return (((a) > (b)) ? (a) : (b)); |
|
543 } |
|
544 static OPUS_INLINE opus_int64 silk_max_64(opus_int64 a, opus_int64 b) |
|
545 { |
|
546 return (((a) > (b)) ? (a) : (b)); |
|
547 } |
|
548 |
|
549 #define silk_LIMIT( a, limit1, limit2) ((limit1) > (limit2) ? ((a) > (limit1) ? (limit1) : ((a) < (limit2) ? (limit2) : (a))) \ |
|
550 : ((a) > (limit2) ? (limit2) : ((a) < (limit1) ? (limit1) : (a)))) |
|
551 |
|
552 #define silk_LIMIT_int silk_LIMIT |
|
553 #define silk_LIMIT_16 silk_LIMIT |
|
554 #define silk_LIMIT_32 silk_LIMIT |
|
555 |
|
556 #define silk_abs(a) (((a) > 0) ? (a) : -(a)) /* Be careful, silk_abs returns wrong when input equals to silk_intXX_MIN */ |
|
557 #define silk_abs_int(a) (((a) ^ ((a) >> (8 * sizeof(a) - 1))) - ((a) >> (8 * sizeof(a) - 1))) |
|
558 #define silk_abs_int32(a) (((a) ^ ((a) >> 31)) - ((a) >> 31)) |
|
559 #define silk_abs_int64(a) (((a) > 0) ? (a) : -(a)) |
|
560 |
|
561 #define silk_sign(a) ((a) > 0 ? 1 : ( (a) < 0 ? -1 : 0 )) |
|
562 |
|
563 /* PSEUDO-RANDOM GENERATOR */ |
|
564 /* 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 */ |
|
566 /* bits, take the most significant bits by right-shifting. */ |
|
567 #define silk_RAND(seed) (silk_MLA_ovflw(907633515, (seed), 196314165)) |
|
568 |
|
569 /* Add some multiplication functions that can be easily mapped to ARM. */ |
|
570 |
|
571 /* silk_SMMUL: Signed top word multiply. |
|
572 ARMv6 2 instruction cycles. |
|
573 ARMv3M+ 3 instruction cycles. use SMULL and ignore LSB registers.(except xM)*/ |
|
574 /*#define silk_SMMUL(a32, b32) (opus_int32)silk_RSHIFT(silk_SMLAL(silk_SMULWB((a32), (b32)), (a32), silk_RSHIFT_ROUND((b32), 16)), 16)*/ |
|
575 /* the following seems faster on x86 */ |
|
576 #define silk_SMMUL(a32, b32) (opus_int32)silk_RSHIFT64(silk_SMULL((a32), (b32)), 32) |
|
577 |
|
578 #include "Inlines.h" |
|
579 #include "MacroCount.h" |
|
580 #include "MacroDebug.h" |
|
581 |
|
582 #ifdef OPUS_ARM_INLINE_ASM |
|
583 #include "arm/SigProc_FIX_armv4.h" |
|
584 #endif |
|
585 |
|
586 #ifdef OPUS_ARM_INLINE_EDSP |
|
587 #include "arm/SigProc_FIX_armv5e.h" |
|
588 #endif |
|
589 |
|
590 #ifdef __cplusplus |
|
591 } |
|
592 #endif |
|
593 |
|
594 #endif /* SILK_SIGPROC_FIX_H */ |