xref: /aosp_15_r20/external/tremolo/Tremolo/misc.h (revision bda690e46497e1f65c5077173b9c548e6e0cd5a1)
1*bda690e4SXin Li /************************************************************************
2*bda690e4SXin Li  * Copyright (C) 2002-2009, Xiph.org Foundation
3*bda690e4SXin Li  * Copyright (C) 2010, Robin Watts for Pinknoise Productions Ltd
4*bda690e4SXin Li  * All rights reserved.
5*bda690e4SXin Li  *
6*bda690e4SXin Li  * Redistribution and use in source and binary forms, with or without
7*bda690e4SXin Li  * modification, are permitted provided that the following conditions
8*bda690e4SXin Li  * are met:
9*bda690e4SXin Li  *
10*bda690e4SXin Li  *     * Redistributions of source code must retain the above copyright
11*bda690e4SXin Li  * notice, this list of conditions and the following disclaimer.
12*bda690e4SXin Li  *     * Redistributions in binary form must reproduce the above
13*bda690e4SXin Li  * copyright notice, this list of conditions and the following disclaimer
14*bda690e4SXin Li  * in the documentation and/or other materials provided with the
15*bda690e4SXin Li  * distribution.
16*bda690e4SXin Li  *     * Neither the names of the Xiph.org Foundation nor Pinknoise
17*bda690e4SXin Li  * Productions Ltd nor the names of its contributors may be used to
18*bda690e4SXin Li  * endorse or promote products derived from this software without
19*bda690e4SXin Li  * specific prior written permission.
20*bda690e4SXin Li  *
21*bda690e4SXin Li  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22*bda690e4SXin Li  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23*bda690e4SXin Li  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24*bda690e4SXin Li  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25*bda690e4SXin Li  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26*bda690e4SXin Li  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27*bda690e4SXin Li  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28*bda690e4SXin Li  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29*bda690e4SXin Li  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30*bda690e4SXin Li  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31*bda690e4SXin Li  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32*bda690e4SXin Li  ************************************************************************
33*bda690e4SXin Li 
34*bda690e4SXin Li  function: miscellaneous math and prototypes
35*bda690e4SXin Li 
36*bda690e4SXin Li  ************************************************************************/
37*bda690e4SXin Li 
38*bda690e4SXin Li #ifndef _V_RANDOM_H_
39*bda690e4SXin Li #define _V_RANDOM_H_
40*bda690e4SXin Li #include "ivorbiscodec.h"
41*bda690e4SXin Li #include "os_types.h"
42*bda690e4SXin Li 
43*bda690e4SXin Li /*#define _VDBG_GRAPHFILE "_0.m"*/
44*bda690e4SXin Li 
45*bda690e4SXin Li 
46*bda690e4SXin Li #ifdef _VDBG_GRAPHFILE
47*bda690e4SXin Li extern void *_VDBG_malloc(void *ptr,long bytes,char *file,long line);
48*bda690e4SXin Li extern void _VDBG_free(void *ptr);
49*bda690e4SXin Li 
50*bda690e4SXin Li #undef _ogg_malloc
51*bda690e4SXin Li #undef _ogg_calloc
52*bda690e4SXin Li #undef _ogg_realloc
53*bda690e4SXin Li #undef _ogg_free
54*bda690e4SXin Li 
55*bda690e4SXin Li #define _ogg_malloc(x) _VDBG_malloc(NULL,(x),__FILE__,__LINE__)
56*bda690e4SXin Li #define _ogg_calloc(x,y) _VDBG_malloc(NULL,(x)*(y),__FILE__,__LINE__)
57*bda690e4SXin Li #define _ogg_realloc(x,y) _VDBG_malloc((x),(y),__FILE__,__LINE__)
58*bda690e4SXin Li #define _ogg_free(x) _VDBG_free((x))
59*bda690e4SXin Li #endif
60*bda690e4SXin Li 
61*bda690e4SXin Li #include "asm_arm.h"
62*bda690e4SXin Li 
63*bda690e4SXin Li #ifndef _V_WIDE_MATH
64*bda690e4SXin Li #define _V_WIDE_MATH
65*bda690e4SXin Li 
66*bda690e4SXin Li #ifndef  _LOW_ACCURACY_
67*bda690e4SXin Li /* 64 bit multiply */
68*bda690e4SXin Li 
69*bda690e4SXin Li #include <endian.h>
70*bda690e4SXin Li #include <sys/types.h>
71*bda690e4SXin Li 
72*bda690e4SXin Li #if BYTE_ORDER==LITTLE_ENDIAN
73*bda690e4SXin Li union magic {
74*bda690e4SXin Li   struct {
75*bda690e4SXin Li     ogg_int32_t lo;
76*bda690e4SXin Li     ogg_int32_t hi;
77*bda690e4SXin Li   } halves;
78*bda690e4SXin Li   ogg_int64_t whole;
79*bda690e4SXin Li };
80*bda690e4SXin Li #endif
81*bda690e4SXin Li 
82*bda690e4SXin Li #if BYTE_ORDER==BIG_ENDIAN
83*bda690e4SXin Li union magic {
84*bda690e4SXin Li   struct {
85*bda690e4SXin Li     ogg_int32_t hi;
86*bda690e4SXin Li     ogg_int32_t lo;
87*bda690e4SXin Li   } halves;
88*bda690e4SXin Li   ogg_int64_t whole;
89*bda690e4SXin Li };
90*bda690e4SXin Li #endif
91*bda690e4SXin Li 
MULT32(ogg_int32_t x,ogg_int32_t y)92*bda690e4SXin Li static inline ogg_int32_t MULT32(ogg_int32_t x, ogg_int32_t y) {
93*bda690e4SXin Li   union magic magic;
94*bda690e4SXin Li   magic.whole = (ogg_int64_t)x * y;
95*bda690e4SXin Li   return magic.halves.hi;
96*bda690e4SXin Li }
97*bda690e4SXin Li 
MULT31(ogg_int32_t x,ogg_int32_t y)98*bda690e4SXin Li static inline ogg_int32_t MULT31(ogg_int32_t x, ogg_int32_t y) {
99*bda690e4SXin Li   return MULT32(x,y)<<1;
100*bda690e4SXin Li }
101*bda690e4SXin Li 
MULT31_SHIFT15(ogg_int32_t x,ogg_int32_t y)102*bda690e4SXin Li static inline ogg_int32_t MULT31_SHIFT15(ogg_int32_t x, ogg_int32_t y) {
103*bda690e4SXin Li   union magic magic;
104*bda690e4SXin Li   magic.whole  = (ogg_int64_t)x * y;
105*bda690e4SXin Li   return ((ogg_uint32_t)(magic.halves.lo)>>15) | ((magic.halves.hi)<<17);
106*bda690e4SXin Li }
107*bda690e4SXin Li 
108*bda690e4SXin Li #else
109*bda690e4SXin Li /* 32 bit multiply, more portable but less accurate */
110*bda690e4SXin Li 
111*bda690e4SXin Li /*
112*bda690e4SXin Li  * Note: Precision is biased towards the first argument therefore ordering
113*bda690e4SXin Li  * is important.  Shift values were chosen for the best sound quality after
114*bda690e4SXin Li  * many listening tests.
115*bda690e4SXin Li  */
116*bda690e4SXin Li 
117*bda690e4SXin Li /*
118*bda690e4SXin Li  * For MULT32 and MULT31: The second argument is always a lookup table
119*bda690e4SXin Li  * value already preshifted from 31 to 8 bits.  We therefore take the
120*bda690e4SXin Li  * opportunity to save on text space and use unsigned char for those
121*bda690e4SXin Li  * tables in this case.
122*bda690e4SXin Li  */
123*bda690e4SXin Li 
MULT32(ogg_int32_t x,ogg_int32_t y)124*bda690e4SXin Li static inline ogg_int32_t MULT32(ogg_int32_t x, ogg_int32_t y) {
125*bda690e4SXin Li   return (x >> 9) * y;  /* y preshifted >>23 */
126*bda690e4SXin Li }
127*bda690e4SXin Li 
MULT31(ogg_int32_t x,ogg_int32_t y)128*bda690e4SXin Li static inline ogg_int32_t MULT31(ogg_int32_t x, ogg_int32_t y) {
129*bda690e4SXin Li   return (x >> 8) * y;  /* y preshifted >>23 */
130*bda690e4SXin Li }
131*bda690e4SXin Li 
MULT31_SHIFT15(ogg_int32_t x,ogg_int32_t y)132*bda690e4SXin Li static inline ogg_int32_t MULT31_SHIFT15(ogg_int32_t x, ogg_int32_t y) {
133*bda690e4SXin Li   return (x >> 6) * y;  /* y preshifted >>9 */
134*bda690e4SXin Li }
135*bda690e4SXin Li 
136*bda690e4SXin Li #endif
137*bda690e4SXin Li 
138*bda690e4SXin Li /*
139*bda690e4SXin Li  * This should be used as a memory barrier, forcing all cached values in
140*bda690e4SXin Li  * registers to wr writen back to memory.  Might or might not be beneficial
141*bda690e4SXin Li  * depending on the architecture and compiler.
142*bda690e4SXin Li  */
143*bda690e4SXin Li #define MB()
144*bda690e4SXin Li 
145*bda690e4SXin Li /*
146*bda690e4SXin Li  * The XPROD functions are meant to optimize the cross products found all
147*bda690e4SXin Li  * over the place in mdct.c by forcing memory operation ordering to avoid
148*bda690e4SXin Li  * unnecessary register reloads as soon as memory is being written to.
149*bda690e4SXin Li  * However this is only beneficial on CPUs with a sane number of general
150*bda690e4SXin Li  * purpose registers which exclude the Intel x86.  On Intel, better let the
151*bda690e4SXin Li  * compiler actually reload registers directly from original memory by using
152*bda690e4SXin Li  * macros.
153*bda690e4SXin Li  */
154*bda690e4SXin Li 
155*bda690e4SXin Li #ifdef __i386__
156*bda690e4SXin Li 
157*bda690e4SXin Li #define XPROD32(_a, _b, _t, _v, _x, _y)		\
158*bda690e4SXin Li   { *(_x)=MULT32(_a,_t)+MULT32(_b,_v);		\
159*bda690e4SXin Li     *(_y)=MULT32(_b,_t)-MULT32(_a,_v); }
160*bda690e4SXin Li #define XPROD31(_a, _b, _t, _v, _x, _y)		\
161*bda690e4SXin Li   { *(_x)=MULT31(_a,_t)+MULT31(_b,_v);		\
162*bda690e4SXin Li     *(_y)=MULT31(_b,_t)-MULT31(_a,_v); }
163*bda690e4SXin Li #define XNPROD31(_a, _b, _t, _v, _x, _y)	\
164*bda690e4SXin Li   { *(_x)=MULT31(_a,_t)-MULT31(_b,_v);		\
165*bda690e4SXin Li     *(_y)=MULT31(_b,_t)+MULT31(_a,_v); }
166*bda690e4SXin Li 
167*bda690e4SXin Li #else
168*bda690e4SXin Li 
169*bda690e4SXin Li __attribute__((no_sanitize("signed-integer-overflow")))
XPROD32(ogg_int32_t a,ogg_int32_t b,ogg_int32_t t,ogg_int32_t v,ogg_int32_t * x,ogg_int32_t * y)170*bda690e4SXin Li static inline void XPROD32(ogg_int32_t  a, ogg_int32_t  b,
171*bda690e4SXin Li 			   ogg_int32_t  t, ogg_int32_t  v,
172*bda690e4SXin Li 			   ogg_int32_t *x, ogg_int32_t *y)
173*bda690e4SXin Li {
174*bda690e4SXin Li   *x = MULT32(a, t) + MULT32(b, v);
175*bda690e4SXin Li   *y = MULT32(b, t) - MULT32(a, v);
176*bda690e4SXin Li }
177*bda690e4SXin Li 
178*bda690e4SXin Li __attribute__((no_sanitize("signed-integer-overflow")))
XPROD31(ogg_int32_t a,ogg_int32_t b,ogg_int32_t t,ogg_int32_t v,ogg_int32_t * x,ogg_int32_t * y)179*bda690e4SXin Li static inline void XPROD31(ogg_int32_t  a, ogg_int32_t  b,
180*bda690e4SXin Li 			   ogg_int32_t  t, ogg_int32_t  v,
181*bda690e4SXin Li 			   ogg_int32_t *x, ogg_int32_t *y)
182*bda690e4SXin Li {
183*bda690e4SXin Li   *x = MULT31(a, t) + MULT31(b, v);
184*bda690e4SXin Li   *y = MULT31(b, t) - MULT31(a, v);
185*bda690e4SXin Li }
186*bda690e4SXin Li 
187*bda690e4SXin Li __attribute__((no_sanitize("signed-integer-overflow")))
XNPROD31(ogg_int32_t a,ogg_int32_t b,ogg_int32_t t,ogg_int32_t v,ogg_int32_t * x,ogg_int32_t * y)188*bda690e4SXin Li static inline void XNPROD31(ogg_int32_t  a, ogg_int32_t  b,
189*bda690e4SXin Li 			    ogg_int32_t  t, ogg_int32_t  v,
190*bda690e4SXin Li 			    ogg_int32_t *x, ogg_int32_t *y)
191*bda690e4SXin Li {
192*bda690e4SXin Li   *x = MULT31(a, t) - MULT31(b, v);
193*bda690e4SXin Li   *y = MULT31(b, t) + MULT31(a, v);
194*bda690e4SXin Li }
195*bda690e4SXin Li 
196*bda690e4SXin Li #endif
197*bda690e4SXin Li 
198*bda690e4SXin Li #endif
199*bda690e4SXin Li 
200*bda690e4SXin Li #ifndef _V_CLIP_MATH
201*bda690e4SXin Li #define _V_CLIP_MATH
202*bda690e4SXin Li 
CLIP_TO_15(ogg_int32_t x)203*bda690e4SXin Li static inline ogg_int32_t CLIP_TO_15(ogg_int32_t x) {
204*bda690e4SXin Li   int ret=x;
205*bda690e4SXin Li   ret-= ((x<=32767)-1)&(x-32767);
206*bda690e4SXin Li   ret-= ((x>=-32768)-1)&(x+32768);
207*bda690e4SXin Li   return(ret);
208*bda690e4SXin Li }
209*bda690e4SXin Li 
210*bda690e4SXin Li #endif
211*bda690e4SXin Li 
212*bda690e4SXin Li #endif
213*bda690e4SXin Li 
214*bda690e4SXin Li 
215*bda690e4SXin Li 
216*bda690e4SXin Li 
217