Initial import to Tizen
[profile/ivi/sphinxbase.git] / include / sphinxbase / fixpoint.h
1 /* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* ====================================================================
3  * Copyright (c) 2005 Carnegie Mellon University.  All rights 
4  * reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer. 
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  *
18  * This work was supported in part by funding from the Defense Advanced 
19  * Research Projects Agency and the National Science Foundation of the 
20  * United States of America, and the CMU Sphinx Speech Consortium.
21  *
22  * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND 
23  * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
24  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY
26  * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
28  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
32  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  *
34  * ==================================================================== */
35
36 /* Fixed-point arithmetic macros.
37  *
38  * Author: David Huggins-Daines <dhuggins@cs.cmu.edu>
39  */
40
41 #ifndef _FIXPOINT_H_
42 #define _FIXPOINT_H_
43
44 #include <limits.h>
45
46 /* Win32/WinCE DLL gunk */
47 #include <sphinxbase/sphinxbase_export.h>
48 #include <sphinxbase/prim_type.h>
49
50 #ifdef __cplusplus
51 extern "C" {
52 #endif
53 #if 0
54 /* Fool Emacs. */
55 }
56 #endif
57
58 #ifndef DEFAULT_RADIX
59 #define DEFAULT_RADIX 12
60 #endif
61
62 /** Fixed-point computation type. */
63 typedef int32 fixed32;
64
65 /** Convert floating point to fixed point. */
66 #define FLOAT2FIX_ANY(x,radix) \
67         (((x)<0.0) ? \
68         ((fixed32)((x)*(float32)(1<<(radix)) - 0.5)) \
69         : ((fixed32)((x)*(float32)(1<<(radix)) + 0.5)))
70 #define FLOAT2FIX(x) FLOAT2FIX_ANY(x,DEFAULT_RADIX)
71 /** Convert fixed point to floating point. */
72 #define FIX2FLOAT_ANY(x,radix) ((float32)(x)/(1<<(radix)))
73 #define FIX2FLOAT(x) FIX2FLOAT_ANY(x,DEFAULT_RADIX)
74
75 /**
76  * Multiply two fixed point numbers with an arbitrary radix point.
77  *
78  * A veritable multiplicity of implementations exist, starting with
79  * the fastest ones...
80  */
81
82
83 /* 
84  * This works on most modern ARMs but *only* in ARM mode (for obvious
85  * reasons), so don't use it in Thumb mode (but why are you building
86  * signal processing code in Thumb mode?!)
87  */
88 #if defined(__arm__) && !defined(__thumb__)
89 #define FIXMUL(a,b) FIXMUL_ANY(a,b,DEFAULT_RADIX)
90 #define FIXMUL_ANY(a,b,r) ({                            \
91       int cl, ch, _a = a, _b = b;                       \
92       __asm__ ("smull %0, %1, %2, %3\n"                 \
93            "mov %0, %0, lsr %4\n"                       \
94            "orr %0, %0, %1, lsl %5\n"                   \
95            : "=&r" (cl), "=&r" (ch)                     \
96            : "r" (_a), "r" (_b), "i" (r), "i" (32-(r)));\
97       cl; })
98 #elif defined(BFIN) && DEFAULT_RADIX == 16
99 /* Blackfin magic */
100 #undef FIXMUL
101 /* Use the accumulators for the 16.16 case (probably not as efficient as it could be). */
102 #define FIXMUL(a,b) ({                                  \
103       int c, _a = a, _b = b;                            \
104         __asm__("%0.L = %1.l * %2.l (FU);\n\t"          \
105             "%0.H = %1.h * %2.h (IS);\n\t"              \
106             "A1 = %0;\n\t"                              \
107             "A1 += %1.h * %2.l (IS, M);\n\t"            \
108             "%0 = (A1 += %2.h * %1.l) (IS, M);\n\t"     \
109             : "=&W" (c)                                 \
110             : "d" (_a), "d" (_b)                        \
111             : "A1", "cc");                                      \
112       c; })
113 #define FIXMUL_ANY(a,b,radix) ((fixed32)(((int64)(a)*(b))>>(radix)))
114 #elif defined(_MSC_VER) || (defined(HAVE_LONG_LONG) && SIZEOF_LONG_LONG == 8)
115 #define FIXMUL(a,b) FIXMUL_ANY(a,b,DEFAULT_RADIX)
116 #define FIXMUL_ANY(a,b,radix) ((fixed32)(((int64)(a)*(b))>>(radix)))
117 #else /* Most general case where 'long long' doesn't exist or is slow. */
118 #define FIXMUL(a,b) FIXMUL_ANY(a,b,DEFAULT_RADIX)
119 #define FIXMUL_ANY(a,b,radix) \
120         (fixed32)(((((uint32)(a))&((1<<(radix))-1))         \
121                    * (((uint32)(b))&((1<<(radix))-1)) >> (radix))       \
122         + (((((int32)(a))>>(radix)) * (((int32)(b))>>(radix))) << (radix)) \
123         + ((((uint32)(a))&((1<<(radix))-1)) * (((int32)(b))>>(radix))) \
124         + ((((uint32)(b))&((1<<(radix))-1)) * (((int32)(a))>>(radix))))
125 #endif
126
127 /* Various fixed-point logarithmic functions that we need. */
128 /** Minimum value representable in log format. */
129 #define MIN_FIXLOG -2829416  /* log(1e-300) * (1<<DEFAULT_RADIX) */
130 #define MIN_FIXLOG2 -4081985 /* log2(1e-300) * (1<<DEFAULT_RADIX) */
131 /** Fixed-point representation of log(2) */
132 #define FIXLN_2         ((fixed32)(0.693147180559945 * (1<<DEFAULT_RADIX)))
133 /** Take natural logarithm of a fixedpoint number. */
134 #define FIXLN(x) (fixlog(x) - (FIXLN_2 * DEFAULT_RADIX))
135 /**
136  * Take natural logarithm of an integer, yielding a fixedpoint number
137  * with DEFAULT_RADIX as radix point.
138  */
139 int32 fixlog(uint32 x);
140 /**
141  * Take base-2 logarithm of an integer, yielding a fixedpoint number
142  * with DEFAULT_RADIX as radix point.
143  */
144 int32 fixlog2(uint32 x);
145
146 #ifdef __cplusplus
147 }
148 #endif
149
150
151 #endif /* _FIXPOINT_H_ */