You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

214 lines
4.7KB

  1. /*
  2. ** Copyright (C) 2001-2003 Erik de Castro Lopo <erikd@mega-nerd.com>
  3. **
  4. ** This program is free software; you can redistribute it and/or modify
  5. ** it under the terms of the GNU General Public License as published by
  6. ** the Free Software Foundation; either version 2 of the License, or
  7. ** (at your option) any later version.
  8. **
  9. ** This program is distributed in the hope that it will be useful,
  10. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. ** GNU General Public License for more details.
  13. **
  14. ** You should have received a copy of the GNU General Public License
  15. ** along with this program; if not, write to the Free Software
  16. ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  17. */
  18. /* Version 1.3 */
  19. #ifndef SAMPLERATE_FLOAT_CAST_H
  20. #define SAMPLERATE_FLOAT_CAST_H
  21. /*============================================================================
  22. ** On Intel Pentium processors (especially PIII and probably P4), converting
  23. ** from float to int is very slow. To meet the C specs, the code produced by
  24. ** most C compilers targeting Pentium needs to change the FPU rounding mode
  25. ** before the float to int conversion is performed.
  26. **
  27. ** Changing the FPU rounding mode causes the FPU pipeline to be flushed. It
  28. ** is this flushing of the pipeline which is so slow.
  29. **
  30. ** Fortunately the ISO C99 specifications define the functions lrint, lrintf,
  31. ** llrint and llrintf which fix this problem as a side effect.
  32. **
  33. ** On Unix-like systems, the configure process should have detected the
  34. ** presence of these functions. If they weren't found we have to replace them
  35. ** here with a standard C cast.
  36. */
  37. /*
  38. ** The C99 prototypes for lrint and lrintf are as follows:
  39. **
  40. ** long int lrintf (float x) ;
  41. ** long int lrint (double x) ;
  42. */
  43. #include "config.h"
  44. /*
  45. ** The presence of the required functions are detected during the configure
  46. ** process and the values HAVE_LRINT and HAVE_LRINTF are set accordingly in
  47. ** the config.h file.
  48. */
  49. #define HAVE_LRINT_REPLACEMENT 0
  50. #if (HAVE_LRINT && HAVE_LRINTF)
  51. /*
  52. ** These defines enable functionality introduced with the 1999 ISO C
  53. ** standard. They must be defined before the inclusion of math.h to
  54. ** engage them. If optimisation is enabled, these functions will be
  55. ** inlined. With optimisation switched off, you have to link in the
  56. ** maths library using -lm.
  57. */
  58. #define _ISOC9X_SOURCE 1
  59. #define _ISOC99_SOURCE 1
  60. #define __USE_ISOC9X 1
  61. #define __USE_ISOC99 1
  62. #include <math.h>
  63. #elif (defined (WIN32) || defined (_WIN32))
  64. #undef HAVE_LRINT_REPLACEMENT
  65. #define HAVE_LRINT_REPLACEMENT 1
  66. #include <math.h>
  67. /*
  68. ** Win32 doesn't seem to have these functions.
  69. ** Therefore implement inline versions of these functions here.
  70. */
  71. __inline long int
  72. lrint (double flt)
  73. { int intgr ;
  74. _asm
  75. { fld flt
  76. fistp intgr
  77. } ;
  78. return intgr ;
  79. }
  80. __inline long int
  81. lrintf (float flt)
  82. { int intgr ;
  83. _asm
  84. { fld flt
  85. fistp intgr
  86. } ;
  87. return intgr ;
  88. }
  89. #elif (defined (__MWERKS__) && defined (macintosh))
  90. /* This MacOS 9 solution was provided by Stephane Letz */
  91. #undef HAVE_LRINT_REPLACEMENT
  92. #define HAVE_LRINT_REPLACEMENT 1
  93. #include <math.h>
  94. #undef lrint
  95. #undef lrintf
  96. #define lrint double2int
  97. #define lrintf float2int
  98. inline int
  99. float2int (register float in)
  100. { long res [2] ;
  101. asm
  102. { fctiw in, in
  103. stfd in, res
  104. }
  105. return res [1] ;
  106. } /* float2int */
  107. inline int
  108. double2int (register double in)
  109. { long res [2] ;
  110. asm
  111. { fctiw in, in
  112. stfd in, res
  113. }
  114. return res [1] ;
  115. } /* double2int */
  116. #elif (defined (__MACH__) && defined (__APPLE__))
  117. /* For Apple MacOSX. */
  118. #undef HAVE_LRINT_REPLACEMENT
  119. #define HAVE_LRINT_REPLACEMENT 1
  120. #include <math.h>
  121. #undef lrint
  122. #undef lrintf
  123. #define lrint double2int
  124. #define lrintf float2int
  125. inline static long int
  126. float2int (register float in)
  127. { int res [2] ;
  128. __asm__ __volatile__
  129. ( "fctiw %1, %1\n\t"
  130. "stfd %1, %0"
  131. : "=m" (res) /* Output */
  132. : "f" (in) /* Input */
  133. : "memory"
  134. ) ;
  135. return res [1] ;
  136. } /* lrintf */
  137. inline static long int
  138. double2int (register double in)
  139. { int res [2] ;
  140. __asm__ __volatile__
  141. ( "fctiw %1, %1\n\t"
  142. "stfd %1, %0"
  143. : "=m" (res) /* Output */
  144. : "f" (in) /* Input */
  145. : "memory"
  146. ) ;
  147. return res [1] ;
  148. } /* lrint */
  149. #else
  150. #ifndef __sgi
  151. #warning "Don't have the functions lrint() and lrintf()."
  152. #warning "Replacing these functions with a standard C cast."
  153. #endif
  154. #include <math.h>
  155. #define lrint(dbl) ((long) (dbl))
  156. #define lrintf(flt) ((long) (flt))
  157. #endif
  158. #endif
  159. /*
  160. ** Do not edit or modify anything in this comment block.
  161. ** The arch-tag line is a file identity tag for the GNU Arch
  162. ** revision control system.
  163. **
  164. ** arch-tag: 25418b9e-cfe8-4145-a3b3-a92388dd37c5
  165. */