1885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* Copyright (C) 2001 Erik de Castro Lopo <erikd AT mega-nerd DOT com> */ 2885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* 3885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Redistribution and use in source and binary forms, with or without 4885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org modification, are permitted provided that the following conditions 5885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org are met: 6885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 7885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org - Redistributions of source code must retain the above copyright 8885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org notice, this list of conditions and the following disclaimer. 9885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 10885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org - Redistributions in binary form must reproduce the above copyright 11885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org notice, this list of conditions and the following disclaimer in the 12885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org documentation and/or other materials provided with the distribution. 13885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 14885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 15885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 16885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 17885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 18885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 19885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 21885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 22885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 23885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org*/ 26885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 27885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* Version 1.1 */ 28885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 29885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifndef FLOAT_CAST_H 30885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#define FLOAT_CAST_H 31885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 32885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 33885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "arch.h" 34885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 35885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/*============================================================================ 36885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org** On Intel Pentium processors (especially PIII and probably P4), converting 37885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org** from float to int is very slow. To meet the C specs, the code produced by 38885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org** most C compilers targeting Pentium needs to change the FPU rounding mode 39885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org** before the float to int conversion is performed. 40885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org** 41885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org** Changing the FPU rounding mode causes the FPU pipeline to be flushed. It 42885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org** is this flushing of the pipeline which is so slow. 43885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org** 44885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org** Fortunately the ISO C99 specifications define the functions lrint, lrintf, 45885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org** llrint and llrintf which fix this problem as a side effect. 46885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org** 47885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org** On Unix-like systems, the configure process should have detected the 48885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org** presence of these functions. If they weren't found we have to replace them 49885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org** here with a standard C cast. 50885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org*/ 51885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 52885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* 53885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org** The C99 prototypes for lrint and lrintf are as follows: 54885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org** 55885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org** long int lrintf (float x) ; 56885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org** long int lrint (double x) ; 57885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org*/ 58885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 59885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* The presence of the required functions are detected during the configure 60885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org** process and the values HAVE_LRINT and HAVE_LRINTF are set accordingly in 61885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org** the config.h file. 62885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org*/ 63885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 64885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#if (HAVE_LRINTF) 65885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 66885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* These defines enable functionality introduced with the 1999 ISO C 67885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org** standard. They must be defined before the inclusion of math.h to 68885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org** engage them. If optimisation is enabled, these functions will be 69885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org** inlined. With optimisation switched off, you have to link in the 70885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org** maths library using -lm. 71885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org*/ 72885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 73885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#define _ISOC9X_SOURCE 1 74885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#define _ISOC99_SOURCE 1 75885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 76885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#define __USE_ISOC9X 1 77885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#define __USE_ISOC99 1 78885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 79885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include <math.h> 80885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#define float2int(x) lrintf(x) 81885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 82885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#elif (defined(HAVE_LRINT)) 83885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 84885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#define _ISOC9X_SOURCE 1 85885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#define _ISOC99_SOURCE 1 86885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 87885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#define __USE_ISOC9X 1 88885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#define __USE_ISOC99 1 89885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 90885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include <math.h> 91885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#define float2int(x) lrint(x) 92885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 93885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#elif (defined(_MSC_VER) && _MSC_VER >= 1400) && (defined (WIN64) || defined (_WIN64)) 94885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org #include <xmmintrin.h> 95885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 96885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org __inline long int float2int(float value) 97885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 98885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org return _mm_cvtss_si32(_mm_load_ss(&value)); 99885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 100885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#elif (defined(_MSC_VER) && _MSC_VER >= 1400) && (defined (WIN32) || defined (_WIN32)) 101885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org #include <math.h> 102885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 103885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Win32 doesn't seem to have these functions. 1043c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com ** Therefore implement OPUS_INLINE versions of these functions here. 105885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org */ 106885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 107885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org __inline long int 108885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org float2int (float flt) 109885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { int intgr; 110885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 111885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org _asm 112885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { fld flt 113885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org fistp intgr 114885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } ; 115885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 116885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org return intgr ; 117885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 118885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 119885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#else 120885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 121885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#if (defined(__GNUC__) && defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) 122885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* supported by gcc in C99 mode, but not by all other compilers */ 123885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org #warning "Don't have the functions lrint() and lrintf ()." 124885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org #warning "Replacing these functions with a standard C cast." 125885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif /* __STDC_VERSION__ >= 199901L */ 126885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org #include <math.h> 127885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org #define float2int(flt) ((int)(floor(.5+flt))) 128885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 129885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 130885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifndef DISABLE_FLOAT_API 1313c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.comstatic OPUS_INLINE opus_int16 FLOAT2INT16(float x) 132885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 133885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org x = x*CELT_SIG_SCALE; 134885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org x = MAX32(x, -32768); 135885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org x = MIN32(x, 32767); 136885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org return (opus_int16)float2int(x); 137885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 138885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif /* DISABLE_FLOAT_API */ 139885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 140885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif /* FLOAT_CAST_H */ 141