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 * File: fixlog.c 00037 * 00038 * Description: Fast approximate fixed-point logarithms 00039 * 00040 * Author: David Huggins-Daines <dhuggins@cs.cmu.edu> 00041 * 00042 */ 00043 00044 #ifdef HAVE_CONFIG_H 00045 #include <config.h> 00046 #endif 00047 00048 #include "sphinxbase/prim_type.h" 00049 #include "sphinxbase/fixpoint.h" 00050 00051 #include "fe_internal.h" 00052 00053 /* Table of log2(x/64)*(1<<DEFAULT_RADIX) */ 00054 /* perl -e 'for (0..63) {my $x = 1 + $_/64; print "\t(uint32)(", log($x)/log(2), "*(1<<DEFAULT_RADIX)),\n"}' */ 00055 static uint32 logtable[] = { 00056 (uint32) (0 * (1 << DEFAULT_RADIX)), 00057 (uint32) (0.0223678130284545 * (1 << DEFAULT_RADIX)), 00058 (uint32) (0.0443941193584534 * (1 << DEFAULT_RADIX)), 00059 (uint32) (0.0660891904577724 * (1 << DEFAULT_RADIX)), 00060 (uint32) (0.0874628412503394 * (1 << DEFAULT_RADIX)), 00061 (uint32) (0.108524456778169 * (1 << DEFAULT_RADIX)), 00062 (uint32) (0.129283016944966 * (1 << DEFAULT_RADIX)), 00063 (uint32) (0.149747119504682 * (1 << DEFAULT_RADIX)), 00064 (uint32) (0.169925001442312 * (1 << DEFAULT_RADIX)), 00065 (uint32) (0.189824558880017 * (1 << DEFAULT_RADIX)), 00066 (uint32) (0.20945336562895 * (1 << DEFAULT_RADIX)), 00067 (uint32) (0.228818690495881 * (1 << DEFAULT_RADIX)), 00068 (uint32) (0.247927513443586 * (1 << DEFAULT_RADIX)), 00069 (uint32) (0.266786540694901 * (1 << DEFAULT_RADIX)), 00070 (uint32) (0.285402218862248 * (1 << DEFAULT_RADIX)), 00071 (uint32) (0.303780748177103 * (1 << DEFAULT_RADIX)), 00072 (uint32) (0.321928094887362 * (1 << DEFAULT_RADIX)), 00073 (uint32) (0.339850002884625 * (1 << DEFAULT_RADIX)), 00074 (uint32) (0.357552004618084 * (1 << DEFAULT_RADIX)), 00075 (uint32) (0.375039431346925 * (1 << DEFAULT_RADIX)), 00076 (uint32) (0.39231742277876 * (1 << DEFAULT_RADIX)), 00077 (uint32) (0.409390936137702 * (1 << DEFAULT_RADIX)), 00078 (uint32) (0.426264754702098 * (1 << DEFAULT_RADIX)), 00079 (uint32) (0.442943495848728 * (1 << DEFAULT_RADIX)), 00080 (uint32) (0.459431618637297 * (1 << DEFAULT_RADIX)), 00081 (uint32) (0.475733430966398 * (1 << DEFAULT_RADIX)), 00082 (uint32) (0.491853096329675 * (1 << DEFAULT_RADIX)), 00083 (uint32) (0.507794640198696 * (1 << DEFAULT_RADIX)), 00084 (uint32) (0.523561956057013 * (1 << DEFAULT_RADIX)), 00085 (uint32) (0.539158811108031 * (1 << DEFAULT_RADIX)), 00086 (uint32) (0.554588851677637 * (1 << DEFAULT_RADIX)), 00087 (uint32) (0.569855608330948 * (1 << DEFAULT_RADIX)), 00088 (uint32) (0.584962500721156 * (1 << DEFAULT_RADIX)), 00089 (uint32) (0.599912842187128 * (1 << DEFAULT_RADIX)), 00090 (uint32) (0.614709844115208 * (1 << DEFAULT_RADIX)), 00091 (uint32) (0.62935662007961 * (1 << DEFAULT_RADIX)), 00092 (uint32) (0.643856189774725 * (1 << DEFAULT_RADIX)), 00093 (uint32) (0.658211482751795 * (1 << DEFAULT_RADIX)), 00094 (uint32) (0.672425341971496 * (1 << DEFAULT_RADIX)), 00095 (uint32) (0.686500527183218 * (1 << DEFAULT_RADIX)), 00096 (uint32) (0.700439718141092 * (1 << DEFAULT_RADIX)), 00097 (uint32) (0.714245517666123 * (1 << DEFAULT_RADIX)), 00098 (uint32) (0.727920454563199 * (1 << DEFAULT_RADIX)), 00099 (uint32) (0.741466986401147 * (1 << DEFAULT_RADIX)), 00100 (uint32) (0.754887502163469 * (1 << DEFAULT_RADIX)), 00101 (uint32) (0.768184324776926 * (1 << DEFAULT_RADIX)), 00102 (uint32) (0.78135971352466 * (1 << DEFAULT_RADIX)), 00103 (uint32) (0.794415866350106 * (1 << DEFAULT_RADIX)), 00104 (uint32) (0.807354922057604 * (1 << DEFAULT_RADIX)), 00105 (uint32) (0.820178962415188 * (1 << DEFAULT_RADIX)), 00106 (uint32) (0.832890014164742 * (1 << DEFAULT_RADIX)), 00107 (uint32) (0.845490050944375 * (1 << DEFAULT_RADIX)), 00108 (uint32) (0.857980995127572 * (1 << DEFAULT_RADIX)), 00109 (uint32) (0.870364719583405 * (1 << DEFAULT_RADIX)), 00110 (uint32) (0.882643049361841 * (1 << DEFAULT_RADIX)), 00111 (uint32) (0.894817763307944 * (1 << DEFAULT_RADIX)), 00112 (uint32) (0.906890595608518 * (1 << DEFAULT_RADIX)), 00113 (uint32) (0.918863237274595 * (1 << DEFAULT_RADIX)), 00114 (uint32) (0.930737337562886 * (1 << DEFAULT_RADIX)), 00115 (uint32) (0.94251450533924 * (1 << DEFAULT_RADIX)), 00116 (uint32) (0.954196310386875 * (1 << DEFAULT_RADIX)), 00117 (uint32) (0.965784284662087 * (1 << DEFAULT_RADIX)), 00118 (uint32) (0.977279923499917 * (1 << DEFAULT_RADIX)), 00119 (uint32) (0.988684686772166 * (1 << DEFAULT_RADIX)), 00120 }; 00121 00122 int32 00123 fixlog2(uint32 x) 00124 { 00125 uint32 y; 00126 00127 if (x == 0) 00128 return MIN_FIXLOG2; 00129 00130 /* Get the exponent. */ 00131 #if defined(__GNUC__) && defined(__i386__) 00132 __asm__("bsrl %1, %0\n": "=r"(y): "g"(x):"cc"); 00133 x <<= (31 - y); 00134 #elif defined(__ppc__) 00135 __asm__("cntlzw %0, %1\n": "=r"(y):"r"(x)); 00136 x <<= y; 00137 y = 31 - y; 00138 #elif ((defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) || \ 00139 defined(__ARM_ARCH_5TE__)) && !defined(__thumb__)) 00140 __asm__("clz %0, %1\n": "=r"(y):"r"(x)); 00141 x <<= y; 00142 y = 31 - y; 00143 #else 00144 for (y = 31; y >= 0; --y) { 00145 if (x & 0x80000000) 00146 break; 00147 x <<= 1; 00148 } 00149 #endif 00150 y <<= DEFAULT_RADIX; 00151 /* Do a table lookup for the MSB of the mantissa. */ 00152 x = (x >> 25) & 0x3f; 00153 return y + logtable[x]; 00154 } 00155 00156 int 00157 fixlog(uint32 x) 00158 { 00159 int32 y; 00160 00161 if (x == 0) 00162 return MIN_FIXLOG; 00163 00164 y = fixlog2(x); 00165 return FIXMUL(y, FIXLN_2); 00166 }