Added Erik de Castro Lopo's float_cast.h to use lrintf() when available. Also
authorJean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Mon, 1 Sep 2008 03:34:47 +0000 (23:34 -0400)
committerJean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Mon, 1 Sep 2008 03:34:47 +0000 (23:34 -0400)
disables the synthesis on the encoder side when pitch is disabled.

acinclude.m4 [new file with mode: 0644]
configure.ac
libcelt/celt.c
libcelt/float_cast.h [new file with mode: 0644]

diff --git a/acinclude.m4 b/acinclude.m4
new file mode 100644 (file)
index 0000000..1346177
--- /dev/null
@@ -0,0 +1,44 @@
+dnl @synopsis AC_C99_FUNC_LRINTF
+dnl
+dnl Check whether C99's lrintf function is available.
+dnl @version 1.1
+dnl @author Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+dnl
+dnl Permission to use, copy, modify, distribute, and sell this file for any 
+dnl purpose is hereby granted without fee, provided that the above copyright 
+dnl and this permission notice appear in all copies.  No representations are
+dnl made about the suitability of this software for any purpose.  It is 
+dnl provided "as is" without express or implied warranty.
+dnl
+AC_DEFUN([AC_C99_FUNC_LRINTF],
+[AC_CACHE_CHECK(for lrintf,
+  ac_cv_c99_lrintf,
+[AC_TRY_COMPILE([
+#define                _ISOC9X_SOURCE  1
+#define        _ISOC99_SOURCE  1
+#define                __USE_ISOC99    1
+#define        __USE_ISOC9X    1
+#include       <math.h>],
+[      int value = lrintf (0.432) ; ], ac_cv_c99_lrintf=yes, ac_cv_c99_lrintf=no)])
+if test $ac_cv_c99_lrintf = yes; then
+  AC_DEFINE(HAVE_LRINTF, 1,
+            [Define if you have C99's lrintf function.])
+fi
+])# AC_C99_LRINTF
+
+AC_DEFUN([AC_C99_FUNC_LRINT],
+[AC_CACHE_CHECK(for lrint,
+  ac_cv_c99_lrint,
+[AC_TRY_COMPILE([
+#define                _ISOC9X_SOURCE  1
+#define        _ISOC99_SOURCE  1
+#define                __USE_ISOC99    1
+#define        __USE_ISOC9X    1
+#include       <math.h>],
+[      int value = lrint (0.432) ; ], ac_cv_c99_lrint=yes, ac_cv_c99_lrint=no)])
+if test $ac_cv_c99_lrint = yes; then
+  AC_DEFINE(HAVE_LRINT, 1,
+            [Define if you have C99's lrint function.])
+fi
+])# AC_C99_LRINT
+
index 330162d..befb94f 100644 (file)
@@ -118,6 +118,9 @@ if test $ac_cv_c_compiler_gnu = yes ; then
         #CFLAGS="$CFLAGS -fvisibility=hidden -W -Wstrict-prototypes -Wmissing-prototypes -Wall -Waggregate-return -Wcast-align -Wcast-qual -Wnested-externs -Wshadow -Wno-parentheses"
 fi
 
+AC_C99_FUNC_LRINTF
+AC_C99_FUNC_LRINT
+
 AC_CHECK_SIZEOF(short)
 AC_CHECK_SIZEOF(int)
 AC_CHECK_SIZEOF(long)
index d9124f9..b99bbf0 100644 (file)
@@ -50,6 +50,7 @@
 #include "rate.h"
 #include "stack_alloc.h"
 #include "mathops.h"
+#include "float_cast.h"
 
 static const celt_word16_t preemph = QCONST16(0.8f,15);
 
@@ -163,7 +164,7 @@ static inline celt_int16_t FLOAT2INT16(float x)
    x = x*32768.;
    x = MAX32(x, -32768);
    x = MIN32(x, 32767);
-   return (celt_int16_t)floor(.5+x);
+   return (celt_int16_t)float2int(x);
 }
 
 static inline celt_word16_t SIG2WORD16(celt_sig_t x)
@@ -598,31 +599,32 @@ int celt_encode_float(CELTEncoder * restrict st, celt_sig_t * restrict pcm, unsi
    /* Residual quantisation */
    quant_bands(st->mode, X, P, NULL, bandE, stereo_mode, pulses, shortBlocks, &st->enc);
    
-   if (C==2)
+   if (st->pitch_enabled)
    {
-      renormalise_bands(st->mode, X);
-   }
-   /* Synthesis */
-   denormalise_bands(st->mode, X, freq, bandE);
-
-
-   CELT_MOVE(st->out_mem, st->out_mem+C*N, C*(MAX_PERIOD+st->overlap-N));
-
-   compute_inv_mdcts(st->mode, shortBlocks, freq, transient_time, transient_shift, st->out_mem);
-   /* De-emphasis and put everything back at the right place in the synthesis history */
+      if (C==2)
+         renormalise_bands(st->mode, X);
+      /* Synthesis */
+      denormalise_bands(st->mode, X, freq, bandE);
+      
+      
+      CELT_MOVE(st->out_mem, st->out_mem+C*N, C*(MAX_PERIOD+st->overlap-N));
+      
+      compute_inv_mdcts(st->mode, shortBlocks, freq, transient_time, transient_shift, st->out_mem);
+      /* De-emphasis and put everything back at the right place in the synthesis history */
 #ifndef SHORTCUTS
-   for (c=0;c<C;c++)
-   {
-      int j;
-      for (j=0;j<N;j++)
+      for (c=0;c<C;c++)
       {
-         celt_sig_t tmp = ADD32(st->out_mem[C*(MAX_PERIOD-N)+C*j+c],
-                                MULT16_32_Q15(preemph,st->preemph_memD[c]));
-         st->preemph_memD[c] = tmp;
-         pcm[C*j+c] = SCALEOUT(SIG2WORD16(tmp));
+         int j;
+         for (j=0;j<N;j++)
+         {
+            celt_sig_t tmp = ADD32(st->out_mem[C*(MAX_PERIOD-N)+C*j+c],
+                                   MULT16_32_Q15(preemph,st->preemph_memD[c]));
+            st->preemph_memD[c] = tmp;
+            pcm[C*j+c] = SCALEOUT(SIG2WORD16(tmp));
+         }
       }
-   }
 #endif
+   }
    /*if (ec_enc_tell(&st->enc, 0) < nbCompressedBytes*8 - 7)
       celt_warning_int ("many unused bits: ", nbCompressedBytes*8-ec_enc_tell(&st->enc, 0));*/
    /*printf ("%d\n", ec_enc_tell(&st->enc, 0)-8*nbCompressedBytes);*/
diff --git a/libcelt/float_cast.h b/libcelt/float_cast.h
new file mode 100644 (file)
index 0000000..9e74c69
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+** Copyright (C) 2001 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+**
+** Permission to use, copy, modify, distribute, and sell this file for any 
+** purpose is hereby granted without fee, provided that the above copyright 
+** and this permission notice appear in all copies.  No representations are
+** made about the suitability of this software for any purpose.  It is 
+** provided "as is" without express or implied warranty.
+*/
+
+/* Version 1.1 */
+
+#ifndef FLOAT_CAST_H
+#define FLOAT_CAST_H
+
+/*============================================================================ 
+**     On Intel Pentium processors (especially PIII and probably P4), converting
+**     from float to int is very slow. To meet the C specs, the code produced by 
+**     most C compilers targeting Pentium needs to change the FPU rounding mode 
+**     before the float to int conversion is performed. 
+**
+**     Changing the FPU rounding mode causes the FPU pipeline to be flushed. It 
+**     is this flushing of the pipeline which is so slow.
+**
+**     Fortunately the ISO C99 specifications define the functions lrint, lrintf,
+**     llrint and llrintf which fix this problem as a side effect. 
+**
+**     On Unix-like systems, the configure process should have detected the 
+**     presence of these functions. If they weren't found we have to replace them 
+**     here with a standard C cast.
+*/
+
+/*     
+**     The C99 prototypes for lrint and lrintf are as follows:
+**     
+**             long int lrintf (float x) ;
+**             long int lrint  (double x) ;
+*/
+
+/*     The presence of the required functions are detected during the configure
+**     process and the values HAVE_LRINT and HAVE_LRINTF are set accordingly in
+**     the config.h file.
+*/
+
+#if (HAVE_LRINTF)
+/*#if 0*/
+
+       /*      These defines enable functionality introduced with the 1999 ISO C
+       **      standard. They must be defined before the inclusion of math.h to
+       **      engage them. If optimisation is enabled, these functions will be 
+       **      inlined. With optimisation switched off, you have to link in the
+       **      maths library using -lm.
+       */
+
+       #define _ISOC9X_SOURCE  1
+       #define _ISOC99_SOURCE  1
+
+       #define __USE_ISOC9X    1
+       #define __USE_ISOC99    1
+
+       #include        <math.h>
+       #define float2int(x) lrintf(x)
+
+#elif (defined(HAVE_LRINT))
+
+#define        _ISOC9X_SOURCE  1
+#define _ISOC99_SOURCE 1
+
+#define        __USE_ISOC9X    1
+#define        __USE_ISOC99    1
+
+#include       <math.h>
+#define float2int(x) lrint(x)
+
+#elif (defined (WIN32) || defined (_WIN32))
+
+       #include        <math.h>
+
+       /*      Win32 doesn't seem to have these functions. 
+       **      Therefore implement inline versions of these functions here.
+       */
+       
+       __inline long int 
+       float2int (float flt)
+       {       int intgr;
+
+               _asm
+               {       fld flt
+                       fistp intgr
+                       } ;
+                       
+               return intgr ;
+       }
+
+#else
+
+       #warning "Don't have the functions lrint() and lrintf ()."
+       #warning "Replacing these functions with a standard C cast."
+
+       #include        <math.h>
+
+       #define float2int(flt)          ((int)(floor(.5+flt)))
+
+#endif
+
+
+#endif /* FLOAT_CAST_H */