| OLD | NEW |
| (Empty) | |
| 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 anal
ysis in schur() and k2a() */ |
| 39 |
| 40 #include <string.h> /* for memset(), memcpy(), m
emmove() */ |
| 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 samplin
g 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 samp
les */ |
| 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 samp
les */ |
| 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 [ floo
r(2*inLen/3) ] */ |
| 86 const opus_int16 *in, /* I Input signal [ inLen
] */ |
| 87 opus_int32 inLen /* I Number of input samp
les */ |
| 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 interlea
ved 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 coeffi
cients, 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 expa
nded (without leading 1) */ |
| 117 const opus_int d, /* I Length of ar
*/ |
| 118 opus_int32 chirp_Q16 /* I Chirp factor (typica
lly 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 expa
nded (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 predi
ction gain in energy domain, Q30 */ |
| 131 const opus_int16 *A_Q12, /* I Prediction coefficien
ts, 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 pred
iction gain in energy domain, Q30 */ |
| 137 const opus_int32 *A_Q24, /* I Prediction coefficie
nts [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 samp
les */ |
| 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 valu
e, max: 2^15-1 */ |
| 173 const opus_int16 *vec, /* I Input vector [len]
*/ |
| 174 const opus_int32 len /* I Length of input vecto
r */ |
| 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 sh
ifting 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 vecto
r */ |
| 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 ene
rgy */ |
| 190 opus_int16 *rc_Q15, /* O reflection coefficie
nts [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 ene
rgy */ |
| 199 opus_int32 rc_Q16[], /* O Reflection coefficie
nts [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 coefficie
nts [order] Q24 */ |
| 207 const opus_int16 *rc_Q15, /* I Reflection coefficie
nts [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 coefficie
nts [order] Q24 */ |
| 214 const opus_int32 *rc_Q16, /* I Reflection coefficie
nts [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 sig
nal */ |
| 226 const opus_int win_type, /* I Selects a window typ
e */ |
| 227 const opus_int length /* I Window length, multi
ple of 4 */ |
| 228 ); |
| 229 |
| 230 /* Compute autocorrelation */ |
| 231 void silk_autocorr( |
| 232 opus_int32 *results, /* O Result (length corre
lationCount) */ |
| 233 opus_int *scale, /* O Scaling of the corre
lation vector */ |
| 234 const opus_int16 *inputData, /* I Input data to correl
ate */ |
| 235 const opus_int inputDataSize, /* I Length of input
*/ |
| 236 const opus_int correlationCount /* I Number of correlatio
n 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 correlati
on; 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 threshol
d 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 (kH
z) */ |
| 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 subfr
ames */ |
| 259 ); |
| 260 |
| 261 /* Compute Normalized Line Spectral Frequencies (NLSFs) from whitening filter co
efficients */ |
| 262 /* If not all roots are found, the a_Q16 coefficients are bandwidth expanded unt
il convergence. */ |
| 263 void silk_A2NLSF( |
| 264 opus_int16 *NLSF, /* O Normalized Line Spec
tral Frequencies in Q15 (0..2^15-1) [d] */ |
| 265 opus_int32 *a_Q16, /* I/O Monic whitening filt
er coefficients in Q16 [d] */ |
| 266 const opus_int d /* I Filter order (must b
e even) */ |
| 267 ); |
| 268 |
| 269 /* compute whitening filter coefficients from normalized line spectral frequenci
es */ |
| 270 void silk_NLSF2A( |
| 271 opus_int16 *a_Q12, /* O monic whitening filt
er coefficients in Q12, [ d ] */ |
| 272 const opus_int16 *NLSF, /* I normalized line spec
tral 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 v
ector */ |
| 278 opus_int *idx, /* O Index vector for th
e 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 v
ector */ |
| 285 opus_int *idx, /* O Index vector for th
e 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 v
ector */ |
| 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 para
meters 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 ve
ctor weights [D] */ |
| 305 const opus_int16 *pNLSF_Q15, /* I Pointer to input ve
ctor [D] */ |
| 306 const opus_int D /* I Input vector dimens
ion (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 va
lue */ |
| 313 opus_int32 A_Q16[], /* O Prediction coefficie
nts (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 predi
ction gain */ |
| 316 const opus_int subfr_length, /* I Input signal subfram
e 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 sh
ift */ |
| 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) * ((c
32) >> 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 o
n undefined behaviour |
| 420 (just standard two's complement implementation-specific behaviour) */ |
| 421 #define silk_ADD32_ovflw(a, b) ((opus_int32)((opus_uint32)(a) + (op
us_uint32)(b))) |
| 422 /* Subtractss two signed 32-bit values in a way that can overflow, while not rel
ying on undefined behaviour |
| 423 (just standard two's complement implementation-specific behaviour) */ |
| 424 #define silk_SUB32_ovflw(a, b) ((opus_int32)((opus_uint32)(a) - (op
us_uint32)(b))) |
| 425 |
| 426 /* Multiply-accumulate macros that allow overflow in the addition (ie, no assert
s 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_int
32)((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_M
AX : \ |
| 445 ((a) < silk_int16_MIN ? silk_int16_M
IN : (a))) |
| 446 #define silk_SAT32(a) ((a) > silk_int32_MAX ? silk_int32_M
AX : \ |
| 447 ((a) < silk_int32_MIN ? silk_int32_M
IN : (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_M
AX : (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)<<(shi
ft))) /* shift >= 0, shift < 16 */ |
| 474 #define silk_LSHIFT32(a, shift) ((opus_int32)((opus_uint32)(a)<<(shi
ft))) /* shift >= 0, shift < 32 */ |
| 475 #define silk_LSHIFT64(a, shift) ((opus_int64)((opus_uint64)(a)<<(shi
ft))) /* 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), sil
k_RSHIFT32( silk_int32_MIN, (shift) ), \ |
| 486 silk_RSHIFT32( silk_int32_MA
X, (shift) ) ), (shift) )) |
| 487 |
| 488 #define silk_LSHIFT_ovflw(a, shift) ((opus_int32)((opus_uint32)(a) << (s
hift))) /* 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) > (limit
1) ? (limit1) : ((a) < (limit2) ? (limit2) : (a))) \ |
| 553 : ((a) > (limit
2) ? (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), 1
96314165)) |
| 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 */ |
| OLD | NEW |