SphinxBase
0.6
|
00001 /* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */ 00002 /* ==================================================================== 00003 * Copyright (c) 2005 Carnegie Mellon University. All rights 00004 * reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions 00008 * are met: 00009 * 00010 * 1. Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * 00013 * 2. Redistributions in binary form must reproduce the above copyright 00014 * notice, this list of conditions and the following disclaimer in 00015 * the documentation and/or other materials provided with the 00016 * distribution. 00017 * 00018 * This work was supported in part by funding from the Defense Advanced 00019 * Research Projects Agency and the National Science Foundation of the 00020 * United States of America, and the CMU Sphinx Speech Consortium. 00021 * 00022 * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND 00023 * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 00024 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00025 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY 00026 * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00027 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00028 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00029 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00030 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00031 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00032 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00033 * 00034 * ==================================================================== */ 00035 00036 /* Fixed-point arithmetic macros. 00037 * 00038 * Author: David Huggins-Daines <dhuggins@cs.cmu.edu> 00039 */ 00040 00041 #ifndef _FIXPOINT_H_ 00042 #define _FIXPOINT_H_ 00043 00044 #include <limits.h> 00045 00046 /* Win32/WinCE DLL gunk */ 00047 #include <sphinxbase/sphinxbase_export.h> 00048 #include <sphinxbase/prim_type.h> 00049 00050 #ifdef __cplusplus 00051 extern "C" { 00052 #endif 00053 #if 0 00054 /* Fool Emacs. */ 00055 } 00056 #endif 00057 00058 #ifndef DEFAULT_RADIX 00059 #define DEFAULT_RADIX 12 00060 #endif 00061 00063 typedef int32 fixed32; 00064 00066 #define FLOAT2FIX_ANY(x,radix) \ 00067 (((x)<0.0) ? \ 00068 ((fixed32)((x)*(float32)(1<<(radix)) - 0.5)) \ 00069 : ((fixed32)((x)*(float32)(1<<(radix)) + 0.5))) 00070 #define FLOAT2FIX(x) FLOAT2FIX_ANY(x,DEFAULT_RADIX) 00071 00072 #define FIX2FLOAT_ANY(x,radix) ((float32)(x)/(1<<(radix))) 00073 #define FIX2FLOAT(x) FIX2FLOAT_ANY(x,DEFAULT_RADIX) 00074 00083 /* 00084 * This works on most modern ARMs but *only* in ARM mode (for obvious 00085 * reasons), so don't use it in Thumb mode (but why are you building 00086 * signal processing code in Thumb mode?!) 00087 */ 00088 #if defined(__arm__) && !defined(__thumb__) 00089 #define FIXMUL(a,b) FIXMUL_ANY(a,b,DEFAULT_RADIX) 00090 #define FIXMUL_ANY(a,b,r) ({ \ 00091 int cl, ch, _a = a, _b = b; \ 00092 __asm__ ("smull %0, %1, %2, %3\n" \ 00093 "mov %0, %0, lsr %4\n" \ 00094 "orr %0, %0, %1, lsl %5\n" \ 00095 : "=&r" (cl), "=&r" (ch) \ 00096 : "r" (_a), "r" (_b), "i" (r), "i" (32-(r)));\ 00097 cl; }) 00098 #elif defined(BFIN) && DEFAULT_RADIX == 16 00099 /* Blackfin magic */ 00100 #undef FIXMUL 00101 /* Use the accumulators for the 16.16 case (probably not as efficient as it could be). */ 00102 #define FIXMUL(a,b) ({ \ 00103 int c, _a = a, _b = b; \ 00104 __asm__("%0.L = %1.l * %2.l (FU);\n\t" \ 00105 "%0.H = %1.h * %2.h (IS);\n\t" \ 00106 "A1 = %0;\n\t" \ 00107 "A1 += %1.h * %2.l (IS, M);\n\t" \ 00108 "%0 = (A1 += %2.h * %1.l) (IS, M);\n\t" \ 00109 : "=&W" (c) \ 00110 : "d" (_a), "d" (_b) \ 00111 : "A1", "cc"); \ 00112 c; }) 00113 #define FIXMUL_ANY(a,b,radix) ((fixed32)(((int64)(a)*(b))>>(radix))) 00114 #elif defined(_MSC_VER) || (defined(HAVE_LONG_LONG) && SIZEOF_LONG_LONG == 8) 00115 #define FIXMUL(a,b) FIXMUL_ANY(a,b,DEFAULT_RADIX) 00116 #define FIXMUL_ANY(a,b,radix) ((fixed32)(((int64)(a)*(b))>>(radix))) 00117 #else /* Most general case where 'long long' doesn't exist or is slow. */ 00118 #define FIXMUL(a,b) FIXMUL_ANY(a,b,DEFAULT_RADIX) 00119 #define FIXMUL_ANY(a,b,radix) \ 00120 (fixed32)(((((uint32)(a))&((1<<(radix))-1)) \ 00121 * (((uint32)(b))&((1<<(radix))-1)) >> (radix)) \ 00122 + (((((int32)(a))>>(radix)) * (((int32)(b))>>(radix))) << (radix)) \ 00123 + ((((uint32)(a))&((1<<(radix))-1)) * (((int32)(b))>>(radix))) \ 00124 + ((((uint32)(b))&((1<<(radix))-1)) * (((int32)(a))>>(radix)))) 00125 #endif 00126 00127 /* Various fixed-point logarithmic functions that we need. */ 00129 #define MIN_FIXLOG -2829416 /* log(1e-300) * (1<<DEFAULT_RADIX) */ 00130 #define MIN_FIXLOG2 -4081985 /* log2(1e-300) * (1<<DEFAULT_RADIX) */ 00131 00132 #define FIXLN_2 ((fixed32)(0.693147180559945 * (1<<DEFAULT_RADIX))) 00133 00134 #define FIXLN(x) (fixlog(x) - (FIXLN_2 * DEFAULT_RADIX)) 00135 00139 int32 fixlog(uint32 x); 00144 int32 fixlog2(uint32 x); 00145 00146 #ifdef __cplusplus 00147 } 00148 #endif 00149 00150 00151 #endif /* _FIXPOINT_H_ */