Line data Source code
1 : /******************************************************************************
2 : * ETSI TS 103 634 V1.5.1 *
3 : * Low Complexity Communication Codec Plus (LC3plus) *
4 : * *
5 : * Copyright licence is solely granted through ETSI Intellectual Property *
6 : * Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
7 : * estoppel or otherwise. *
8 : ******************************************************************************/
9 :
10 : #ifndef __BASOP_UTIL_LC3PLUS_H__
11 : #define __BASOP_UTIL_LC3PLUS_H__
12 :
13 : #include "defines.h"
14 : #include "functions.h"
15 : #include <assert.h>
16 : #include <string.h>
17 :
18 : #define _LONG long
19 : #define _SHORT short
20 : #ifdef _WIN32
21 : #define _INT64 __int64
22 : #else
23 : #define _INT64 long long
24 : #endif
25 :
26 : #define WORD32_BITS 32
27 : #define MAXVAL_WORD32 ((signed)0x7FFFFFFF)
28 : #define MINVAL_WORD32 ((signed)0x80000000)
29 : #define WORD32_FIX_SCALE ((_INT64)(1) << (WORD32_BITS - 1))
30 :
31 : #define WORD16_BITS 16
32 : #define MAXVAL_WORD16 (((signed)0x7FFFFFFF) >> 16)
33 : #define MINVAL_WORD16 (((signed)0x80000000) >> 16)
34 : #define WORD16_FIX_SCALE ((_INT64)(1) << (WORD16_BITS - 1))
35 :
36 : /*!
37 : \def Macro converts a Word32 fixed point to Word16 fixed point <1 with saturation
38 : */
39 : #define WORD322WORD16(val) \
40 : ((((((val) >> (WORD32_BITS - WORD16_BITS - 1)) + 1) > (((_LONG)1 << WORD16_BITS) - 1)) && ((_LONG)(val) > 0)) \
41 : ? (Word16)(_SHORT)(((_LONG)1 << (WORD16_BITS - 1)) - 1) \
42 : : (Word16)(_SHORT)((((val) >> (WORD32_BITS - WORD16_BITS - 1)) + 1) >> 1))
43 :
44 :
45 : /* Word16 Packed Type */
46 : typedef struct
47 : {
48 : struct
49 : {
50 : Word16 re;
51 : Word16 im;
52 : } v;
53 : } PWord16;
54 :
55 : #ifdef ENABLE_HR_MODE
56 : /* Word32 Packed Type */
57 : typedef struct
58 : {
59 : struct
60 : {
61 : Word32 re;
62 : Word32 im;
63 : } v;
64 : } PWord32;
65 : #endif
66 :
67 : #define cast16 move16
68 :
69 : #define LD_DATA_SCALE (6)
70 : #define LD_DATA_SHIFT_I5 (7)
71 :
72 : /************************************************************************/
73 : /*!
74 : \brief Calculate the squareroot of a number given by mantissa and exponent
75 :
76 : Mantissa is in 16/32-bit-fractional format with values between 0 and 1. <br>
77 : For *norm versions mantissa has to be between 0.5 and 1. <br>
78 : The base for the exponent is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$<br>
79 : The exponent is addressed via pointers and will be overwritten with the result.
80 : */
81 :
82 : Word16 Sqrt16_lc3plus( /*!< output mantissa */
83 : Word16 mantissa, /*!< input mantissa */
84 : Word16 *exponent /*!< pointer to exponent */
85 : );
86 :
87 : Word16 ISqrt16( /*!< output mantissa */
88 : Word16 mantissa, /*!< input mantissa */
89 : Word16 *exponent /*!< pointer to exponent */
90 : );
91 :
92 : /*****************************************************************************/
93 : /*!
94 : \brief Calculate the inverse of a number given by mantissa and exponent
95 :
96 : Mantissa is in 16-bit-fractional format with values between 0 and 1. <br>
97 : The base for the exponent is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$<br>
98 : The operand is addressed via pointers and will be overwritten with the result.
99 :
100 : The function uses a table lookup and a newton iteration.
101 : */
102 : Word16 Inv16_lc3plus( /*!< output mantissa */
103 : Word16 mantissa, /*!< input mantissa */
104 : Word16 *exponent /*!< pointer to exponent */
105 : );
106 :
107 : /********************************************************************/
108 : /*!
109 : \brief Calculates the scalefactor needed to normalize input array
110 :
111 : The scalefactor needed to normalize the Word16 input array is returned <br>
112 : If the input array contains only '0', a scalefactor 0 is returned <br>
113 : Scaling factor is determined wrt a normalized target x: 16384 <= x <= 32767 for positive x <br>
114 : and -32768 <= x <= -16384 for negative x
115 : */
116 :
117 : Word16 getScaleFactor16( /* o: measured headroom in range [0..15], 0 if all x[i] == 0 */
118 : const Word16 *x, /* i: array containing 16-bit data */
119 : const Word16 len_x); /* i: length of the array to scan */
120 :
121 : /********************************************************************/
122 : /*!
123 : \brief Calculates the scalefactor needed to normalize input array
124 :
125 : The scalefactor needed to normalize the Word16 input array is returned <br>
126 : If the input array contains only '0', a scalefactor 16 is returned <br>
127 : Scaling factor is determined wrt a normalized target x: 16384 <= x <= 32767 for positive x <br>
128 : and -32768 <= x <= -16384 for negative x
129 : */
130 :
131 : Word16 getScaleFactor16_0( /* o: measured headroom in range [0..15], 16 if all x[i] == 0 */
132 : const Word16 *x, /* i: array containing 16-bit data */
133 : const Word16 len_x); /* i: length of the array to scan */
134 :
135 : /********************************************************************/
136 : /*!
137 : \brief Calculates the scalefactor needed to normalize input array
138 :
139 : The scalefactor needed to normalize the Word32 input array is returned <br>
140 : If the input array contains only '0', a scalefactor 0 is returned <br>
141 : Scaling factor is determined wrt a normalized target x: 1073741824 <= x <= 2147483647 for positive x <br>
142 : and -2147483648 <= x <= -1073741824 for negative x
143 : */
144 :
145 : Word16 getScaleFactor32_lc3plus( /* o: measured headroom in range [0..31], 0 if all x[i] == 0 */
146 : const Word32 *x, /* i: array containing 32-bit data */
147 : const Word16 len_x); /* i: length of the array to scan */
148 :
149 : /********************************************************************/
150 : /*!
151 : \brief Calculates the scalefactor needed to normalize input array
152 :
153 : The scalefactor needed to normalize the Word32 input array is returned <br>
154 : If the input array contains only '0', a scalefactor 32 is returned <br>
155 : Scaling factor is determined wrt a normalized target x: 1073741824 <= x <= 2147483647 for positive x <br>
156 : and -2147483648 <= x <= -1073741824 for negative x
157 : */
158 :
159 : Word16 getScaleFactor32_0( /* o: measured headroom in range [0..31], 32 if all x[i] == 0 */
160 : const Word32 *x, /* i: array containing 32-bit data */
161 : const Word16 len_x); /* i: length of the array to scan */
162 :
163 : /****************************************************************************/
164 : /*!
165 : \brief Does fractional integer division of Word32 arg1 by Word16 arg2
166 :
167 :
168 : \return fractional Word16 integer z = arg1(32bits)/arg2(16bits) , z not normalized
169 : */
170 : Word16 BASOP_Util_Divide3216_Scale_lc3plus(Word32 x, /*!< i : Numerator */
171 : Word16 y, /*!< i : Denominator*/
172 : Word16 *s); /*!< o : Additional scalefactor difference*/
173 :
174 : /****************************************************************************/
175 : /*!
176 : \brief Does fractional division of Word16 arg1 by Word16 arg2
177 :
178 :
179 : \return fractional Q15 Word16 z = arg1(Q15)/arg2(Q15) with scaling s
180 : */
181 : Word16 BASOP_Util_Divide1616_Scale_lc3plus(Word16 x, /*!< i : Numerator*/
182 : Word16 y, /*!< i : Denominator*/
183 : Word16 *s); /*!< o : Additional scalefactor difference*/
184 :
185 : /************************************************************************/
186 : /*!
187 : \brief Binary logarithm with 7 iterations
188 :
189 : \param x
190 :
191 : \return log2(x)/64
192 : */
193 : /************************************************************************/
194 : Word32 BASOP_Util_Log2_lc3plus(Word32 x);
195 :
196 : /************************************************************************/
197 : /*!
198 : \brief Binary power
199 :
200 : Date: 06-JULY-2012 Arthur Tritthart, IIS Fraunhofer Erlangen
201 :
202 : Version with 3 table lookup and 1 linear interpolations
203 :
204 : Algorithm: compute power of 2, argument x is in Q7.25 format
205 : result = 2^(x/64)
206 : We split exponent (x/64) into 5 components:
207 : integer part: represented by b31..b25 (exp)
208 : fractional part 1: represented by b24..b20 (lookup1)
209 : fractional part 2: represented by b19..b15 (lookup2)
210 : fractional part 3: represented by b14..b10 (lookup3)
211 : fractional part 4: represented by b09..b00 (frac)
212 : => result = (lookup1*lookup2*(lookup3+C1*frac)<<3)>>exp
213 :
214 : Due to the fact, that all lookup values contain a factor 0.5
215 : the result has to be shifted by 3 to the right also.
216 : Table exp2_tab_long_lc3plus contains the log2 for 0 to 1.0 in steps
217 : of 1/32, table exp2w_tab_long_lc3plus the log2 for 0 to 1/32 in steps
218 : of 1/1024, table exp2x_tab_long_lc3plus the log2 for 0 to 1/1024 in
219 : steps of 1/32768. Since the 2-logarithm of very very small
220 : negative value is rather linear, we can use interpolation.
221 :
222 : Limitations:
223 :
224 : For x <= 0, the result is fractional positive
225 : For x > 0, the result is integer in range 1...7FFF.FFFF
226 : For x < -31/64, we have to clear the result
227 : For x = 0, the result is ~1.0 (0x7FFF.FFFF)
228 : For x >= 31/64, the result is 0x7FFF.FFFF
229 :
230 : \param x
231 :
232 : \return pow(2,(x/64))
233 : */
234 : /************************************************************************/
235 : Word32 BASOP_Util_InvLog2_lc3plus(Word32 x);
236 :
237 : #ifdef ENABLE_HR_MODE
238 : /* New function which works with positive x, BASOP_Util_InvLog2_lc3plus does not give
239 : accurate results for x > 0 */
240 : Word32 BASOP_Util_InvLog2_pos(Word32 x, Word16 *exp);
241 : #endif
242 :
243 : /**
244 : * \brief Compute dot product of 1 32 bit vectors with itself
245 : * \param x input vector 1
246 : * \param headroom amount of headroom bits the input vector
247 : * \param length the length of the input vector
248 : * \param result_e pointer to where the exponent of the result will be stored into
249 : * \return the dot product of x and x.
250 : */
251 : Word32 Norm32Norm(const Word32 *x, const Word16 headroom, const Word16 length, Word16 *result_e);
252 :
253 : /*!**********************************************************************
254 : \brief Add two values given by mantissa and exponent.
255 :
256 : Mantissas are in 32-bit-fractional format with values between 0 and 1. <br>
257 : The base for exponents is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$<br>
258 :
259 : ************************************************************************/
260 : Word32 BASOP_Util_Add_Mant32Exp_lc3plus /*!< o: normalized result mantissa */
261 : (Word32 a_m, /*!< i: Mantissa of 1st operand a */
262 : Word16 a_e, /*!< i: Exponent of 1st operand a */
263 : Word32 b_m, /*!< i: Mantissa of 2nd operand b */
264 : Word16 b_e, /*!< i: Exponent of 2nd operand b */
265 : Word16 *ptr_e); /*!< o: exponent of result */
266 : /*!**********************************************************************
267 : \brief Returns the comparison result of two normalized values given by mantissa and exponent.
268 : return value: -1: a < b, 0: a == b, 1; a > b
269 :
270 : Mantissas are in 32-bit-fractional format with values between 0 and 1. <br>
271 : The base for exponents is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$<br>
272 :
273 : ************************************************************************/
274 : Word16 BASOP_Util_Cmp_Mant32Exp_lc3plus /*!< o: flag: result of comparison */
275 : (Word32 a_m, /*!< i: Mantissa of 1st operand a */
276 : Word16 a_e, /*!< i: Exponent of 1st operand a */
277 : Word32 b_m, /*!< i: Mantissa of 2nd operand b */
278 : Word16 b_e); /*!< i: Exponent of 2nd operand b */
279 :
280 : /* compare two positive normalized 16 bit mantissa/exponent values */
281 : /* return value: positive if first value greater, negative if second value greater, zero if equal */
282 : Word16 compMantExp16Unorm(Word16 m1, Word16 e1, Word16 m2, Word16 e2);
283 :
284 : void Scale_sig(Word16 x[], /* i/o: signal to scale Qx */
285 : const Word16 lg, /* i : size of x[] Q0 */
286 : const Word16 exp0 /* i : exponent: x = round(x << exp) Qx ?exp */
287 : );
288 : void Copy_Scale_sig(const Word16 x[], /* i : signal to scale input Qx */
289 : Word16 y[], /* o : scaled signal output Qx */
290 : const Word16 lg, /* i : size of x[] Q0 */
291 : const Word16 exp0 /* i : exponent: x = round(x << exp) Qx ?exp */
292 : );
293 :
294 : #ifdef ENABLE_HR_MODE
295 : void Copy_Scale_sig_32(const Word32 x[], /* i : signal to scale input Qx */
296 : Word16 y[], /* o : scaled signal output Qx */
297 : const Word16 lg, /* i : size of x[] Q0 */
298 : const Word16 exp0 /* i : exponent: x = round(x << exp) Qx ?exp */
299 : );
300 : #endif
301 :
302 : Word32 Isqrt_lc3plus(Word32 x, /* (i) Q31: normalized value (1.0 > x >= 0.5) */
303 : Word16 *x_e /* (i/o) Q0 : pointer to exponent */
304 : );
305 :
306 : Word16 BASOP_Util_Log2_16(Word32 x, Word16 x_e);
307 :
308 : Word16 BASOP_Util_InvLog2_16(Word16 x, Word16 *y_e);
309 :
310 : #ifdef ENABLE_HR_MODE
311 : Word32 invFixp(Word32 op_m, Word16 *op_e);
312 : #endif
313 :
314 : #define BASOP_CFFT_MAX_LENGTH 480
315 : void BASOP_cfft_lc3plus(Word32 *re, Word32 *im, Word16 sizeOfFft, Word16 s, Word16 *scale, Word32 *x);
316 : void BASOP_rfftN(Word32 *re, Word16 sizeOfFft, Word16 *scale, Word8 *scratchBuffer);
317 : void BASOP_irfftN(Word32 *re, Word16 sizeOfFft, Word16 *scale, Word8 *scratchBuffer);
318 :
319 0 : static __inline void basop_memcpy(void *dst, const void *src, size_t n)
320 : {
321 : #ifdef WMOPS
322 : multiCounter[currCounter].move16 += (UWord32)n / 2;
323 : #endif
324 : /* check for overlapping memory */
325 0 : assert((const char *)src + n <= (char *)dst || (char *)dst + n <= (const char *)src);
326 0 : memcpy(dst, src, n);
327 0 : }
328 :
329 0 : static __inline void basop_memmove(void *dst, const void *src, size_t n)
330 : {
331 : #ifdef WMOPS
332 : multiCounter[currCounter].move16 += (UWord32)n / 2;
333 : #endif
334 0 : memmove(dst, src, n);
335 0 : }
336 :
337 0 : static __inline void basop_memset(void *dst, int val, size_t n)
338 : {
339 : #ifdef WMOPS
340 : multiCounter[currCounter].move16 += (UWord32)n / 2;
341 : #endif
342 0 : memset(dst, val, n);
343 0 : }
344 :
345 : /* Macros around Dyn_Mem that don't require duplicate declarations. */
346 : #ifdef DYNMEM_COUNT
347 : /* older visual studio doesn't have __func__ */
348 : #if defined _MSC_VER && _MSC_VER < 1900
349 : #define __func__ __FUNCTION__
350 : #endif
351 : #define Dyn_Mem_Deluxe_In(...) __VA_ARGS__ Dyn_Mem_In(__func__, sizeof(struct {__VA_ARGS__}))
352 : #define Dyn_Mem_Deluxe_Out() Dyn_Mem_Out()
353 : #else
354 : #define Dyn_Mem_Deluxe_In(...) __VA_ARGS__
355 : #define Dyn_Mem_Deluxe_Out()
356 : #endif
357 :
358 : /* Macros missing from IVAS BASOP, used only in LC3plus */
359 : #define L_shl_pos(x, y) (L_shl((x), (y)))
360 : #define L_shr_pos(x, y) (L_shr((x), (y)))
361 : #define L_shr_pos_pos(x, y) (L_shr((x), (y)))
362 :
363 : #define L_shr_r_pos(x, shift) (L_shr_r(x, shift))
364 :
365 : #define shl_pos(x, y) (shl((x), (y)))
366 : #define shr_pos(x, y) (shr((x), (y)))
367 : #define shr_pos_pos(x, y) (shr((x), (y)))
368 :
369 : #define lshl_pos(x, y) (lshl(x, y))
370 : #define UL_lshr_pos(x, y) (UL_lshr(x, y))
371 : #define UL_lshl_pos(x, y) (UL_lshl(x, y))
372 : #endif /* __BASOP_UTIL_LC3PLUS_H__ */
|