gst/speexresample/: Update Speex resampler with latest version from Speex GIT.
authorSebastian Dröge <slomo@circular-chaos.org>
Tue, 28 Oct 2008 11:46:28 +0000 (11:46 +0000)
committerSebastian Dröge <slomo@circular-chaos.org>
Tue, 28 Oct 2008 11:46:28 +0000 (11:46 +0000)
Original commit message from CVS:
* gst/speexresample/README:
* gst/speexresample/arch.h:
* gst/speexresample/fixed_arm4.h:
* gst/speexresample/fixed_arm5e.h:
* gst/speexresample/fixed_bfin.h:
* gst/speexresample/fixed_debug.h:
* gst/speexresample/fixed_generic.h:
* gst/speexresample/resample.c: (compute_func), (main), (sinc),
(cubic_coef), (resampler_basic_direct_single),
(resampler_basic_direct_double),
(resampler_basic_interpolate_single),
(resampler_basic_interpolate_double), (update_filter),
(speex_resampler_init_frac), (speex_resampler_process_native),
(speex_resampler_magic), (speex_resampler_process_float),
(speex_resampler_process_int),
(speex_resampler_process_interleaved_float),
(speex_resampler_process_interleaved_int),
(speex_resampler_set_rate_frac), (speex_resampler_skip_zeros),
(speex_resampler_reset_mem):
* gst/speexresample/speex_resampler.h:
Update Speex resampler with latest version from Speex GIT.

ChangeLog
gst/speexresample/README
gst/speexresample/arch.h
gst/speexresample/fixed_arm4.h [new file with mode: 0644]
gst/speexresample/fixed_arm5e.h [new file with mode: 0644]
gst/speexresample/fixed_bfin.h [new file with mode: 0644]
gst/speexresample/fixed_debug.h [new file with mode: 0644]
gst/speexresample/fixed_generic.h
gst/speexresample/resample.c
gst/speexresample/speex_resampler.h

index 802bbcf..7114191 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,27 @@
+2008-10-28  Sebastian Dröge  <slomo@circular-chaos.org>
+
+       * gst/speexresample/README:
+       * gst/speexresample/arch.h:
+       * gst/speexresample/fixed_arm4.h:
+       * gst/speexresample/fixed_arm5e.h:
+       * gst/speexresample/fixed_bfin.h:
+       * gst/speexresample/fixed_debug.h:
+       * gst/speexresample/fixed_generic.h:
+       * gst/speexresample/resample.c: (compute_func), (main), (sinc),
+       (cubic_coef), (resampler_basic_direct_single),
+       (resampler_basic_direct_double),
+       (resampler_basic_interpolate_single),
+       (resampler_basic_interpolate_double), (update_filter),
+       (speex_resampler_init_frac), (speex_resampler_process_native),
+       (speex_resampler_magic), (speex_resampler_process_float),
+       (speex_resampler_process_int),
+       (speex_resampler_process_interleaved_float),
+       (speex_resampler_process_interleaved_int),
+       (speex_resampler_set_rate_frac), (speex_resampler_skip_zeros),
+       (speex_resampler_reset_mem):
+       * gst/speexresample/speex_resampler.h:
+       Update Speex resampler with latest version from Speex GIT.
+
 2008-10-27  Michael Smith <msmith@songbirdnest.com>
 
        * gst/aiffparse/aiffparse.c:
index 68d8c29..79e11b3 100644 (file)
@@ -1,66 +1,48 @@
-resample.c
-arch.h
-fixed_generic.h
-speex_resampler.h
+ arch.h            
+ fixed_arm4.h      
+ fixed_arm5e.h     
+ fixed_bfin.h      
+ fixed_debug.h     
+ fixed_generic.h   
+ resample.c        
+ speex_resampler.h 
 
-are taken from http://svn.xiph.org/trunk/speex/ revision 14232.
+are taken from http://git.xiph.org/speex.git/ as of 2008-10-28.
 
 The only changes are:
 
---- speex/libspeex/arch.h       2007-11-21 11:05:46.000000000 +0100
-+++ speexresample/arch.h      2007-11-20 05:41:09.000000000 +0100
-@@ -78,7 +78,9 @@
- #include "speex/speex_types.h"
+--- arch.h     2008-10-28 12:21:37.000000000 +0100
++++ arch.h     2008-10-28 12:27:56.000000000 +0100
+@@ -78,7 +78,10 @@
+ #include "../include/speex/speex_types.h"
  #endif
  
 +#ifndef ABS
  #define ABS(x) ((x) < 0 ? (-(x)) : (x))      /**< Absolute integer value. */
 +#endif
++
  #define ABS16(x) ((x) < 0 ? (-(x)) : (x))    /**< Absolute 16-bit value.  */
  #define MIN16(a,b) ((a) < (b) ? (a) : (b))   /**< Maximum 16-bit value.   */
  #define MAX16(a,b) ((a) > (b) ? (a) : (b))   /**< Maximum 16-bit value.   */
-
---- speex/include/speex/speex_resampler.h       2007-11-21 11:05:44.000000000 +0100
-+++ speexresample/speex_resampler.h   2007-11-21 11:10:02.000000000 +0100
-@@ -41,6 +41,8 @@
- #ifdef OUTSIDE_SPEEX
-+#include <glib.h>
-+
- /********* WARNING: MENTAL SANITY ENDS HERE *************/
- /* If the resampler is defined outside of Speex, we change the symbol names so that 
-@@ -75,10 +77,10 @@
- #define speex_resampler_reset_mem CAT_PREFIX(RANDOM_PREFIX,_resampler_reset_mem)
- #define speex_resampler_strerror CAT_PREFIX(RANDOM_PREFIX,_resampler_strerror)
--#define spx_int16_t short
--#define spx_int32_t int
--#define spx_uint16_t unsigned short
--#define spx_uint32_t unsigned int
-+#define spx_int16_t gint16
-+#define spx_int32_t gint32
-+#define spx_uint16_t guint16
-+#define spx_uint32_t guint32
-       
- #else /* OUTSIDE_SPEEX */
-
---- speex/libspeex/resample.c  2007-11-25 14:15:38.000000000 +0100
-+++ speexresample/resample.c   2007-11-25 14:15:31.000000000 +0100
-@@ -62,20 +62,23 @@
+--- resample.c 2008-10-28 12:21:35.000000000 +0100
++++ resample.c 2008-10-28 12:33:46.000000000 +0100
+@@ -63,22 +63,27 @@
  
  #ifdef OUTSIDE_SPEEX
  #include <stdlib.h>
 -static void *
++
 +#include <glib.h>
 +
++#define EXPORT
++
 +static inline void *
  speex_alloc (int size)
  {
 -  return calloc (size, 1);
 +  return g_malloc0 (size);
  }
 -static void *
 +static inline void *
  speex_realloc (void *ptr, int size)
@@ -68,8 +50,8 @@ The only changes are:
 -  return realloc (ptr, size);
 +  return g_realloc (ptr, size);
  }
 -static void
-+
 +static inline void
  speex_free (void *ptr)
  {
@@ -78,3 +60,28 @@ The only changes are:
  }
  
  #include "speex_resampler.h"
+@@ -90,7 +95,6 @@
+ #include "os_support.h"
+ #endif /* OUTSIDE_SPEEX */
+-#include "stack_alloc.h"
+ #include <math.h>
+ #ifndef M_PI
+--- speex_resampler.h  2008-10-28 12:21:37.000000000 +0100
++++ speex_resampler.h  2008-10-28 12:30:48.000000000 +0100
+@@ -77,10 +77,10 @@
+ #define speex_resampler_reset_mem CAT_PREFIX(RANDOM_PREFIX,_resampler_reset_mem)
+ #define speex_resampler_strerror CAT_PREFIX(RANDOM_PREFIX,_resampler_strerror)
+-#define spx_int16_t short
+-#define spx_int32_t int
+-#define spx_uint16_t unsigned short
+-#define spx_uint32_t unsigned int
++#define spx_int16_t gint16
++#define spx_int32_t gint32
++#define spx_uint16_t guint16
++#define spx_uint32_t guint32
+ #else /* OUTSIDE_SPEEX */
index 3b341f0..168f28b 100644 (file)
@@ -40,7 +40,7 @@
 #define SPEEX_MINOR_VERSION 1         /**< Minor Speex version. */
 #define SPEEX_MICRO_VERSION 15        /**< Micro Speex version. */
 #define SPEEX_EXTRA_VERSION ""        /**< Extra Speex version. */
-#define SPEEX_VERSION "speex-1.2beta4"  /**< Speex version string. */
+#define SPEEX_VERSION "speex-1.2beta3"  /**< Speex version string. */
 #endif
 
 /* A couple test to catch stupid option combinations */
 #endif
 
 #ifndef OUTSIDE_SPEEX
-#include "speex/speex_types.h"
+#include "../include/speex/speex_types.h"
 #endif
 
 #ifndef ABS
 #define ABS(x) ((x) < 0 ? (-(x)) : (x))      /**< Absolute integer value. */
 #endif
+
 #define ABS16(x) ((x) < 0 ? (-(x)) : (x))    /**< Absolute 16-bit value.  */
 #define MIN16(a,b) ((a) < (b) ? (a) : (b))   /**< Maximum 16-bit value.   */
 #define MAX16(a,b) ((a) > (b) ? (a) : (b))   /**< Maximum 16-bit value.   */
@@ -91,7 +92,7 @@
 #ifdef FIXED_POINT
 
 typedef spx_int16_t spx_word16_t;
-typedef spx_int32_t   spx_word32_t;
+typedef spx_int32_t spx_word32_t;
 typedef spx_word32_t spx_mem_t;
 typedef spx_word16_t spx_coef_t;
 typedef spx_word16_t spx_lsp_t;
@@ -219,11 +220,11 @@ typedef float spx_word32_t;
 #if defined (CONFIG_TI_C54X) || defined (CONFIG_TI_C55X)
 
 /* 2 on TI C5x DSP */
-#define BYTES_PER_CHAR 2 
+#define BYTES_PER_CHAR 2
 #define BITS_PER_CHAR 16
 #define LOG2_BITS_PER_CHAR 4
 
-#else 
+#else
 
 #define BYTES_PER_CHAR 1
 #define BITS_PER_CHAR 8
@@ -234,7 +235,7 @@ typedef float spx_word32_t;
 
 
 #ifdef FIXED_DEBUG
-long long spx_mips=0;
+extern long long spx_mips;
 #endif
 
 
diff --git a/gst/speexresample/fixed_arm4.h b/gst/speexresample/fixed_arm4.h
new file mode 100644 (file)
index 0000000..df99a60
--- /dev/null
@@ -0,0 +1,130 @@
+/* Copyright (C) 2004 Jean-Marc Valin */
+/**
+   @file fixed_arm4.h
+   @brief ARM4 fixed-point operations
+*/
+/*
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
+   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef FIXED_ARM4_H
+#define FIXED_ARM4_H
+
+#undef MULT16_32_Q14
+static inline spx_word32_t
+MULT16_32_Q14 (spx_word16_t x, spx_word32_t y)
+{
+  int res;
+  int dummy;
+asm ("smull  %0,%1,%2,%3 \n\t" "mov %0, %0, lsr #14 \n\t" "add %0, %0, %1, lsl #18 \n\t":"=&r" (res),
+      "=&r"
+      (dummy)
+:    "r" (y), "r" ((int) x));
+  return (res);
+}
+
+#undef MULT16_32_Q15
+static inline spx_word32_t
+MULT16_32_Q15 (spx_word16_t x, spx_word32_t y)
+{
+  int res;
+  int dummy;
+asm ("smull  %0,%1,%2,%3 \n\t" "mov %0, %0, lsr #15 \n\t" "add %0, %0, %1, lsl #17 \n\t":"=&r" (res),
+      "=&r"
+      (dummy)
+:    "r" (y), "r" ((int) x));
+  return (res);
+}
+
+#undef DIV32_16
+static inline short
+DIV32_16 (int a, int b)
+{
+  int res = 0;
+  int dead1, dead2, dead3, dead4, dead5;
+  __asm__ __volatile__ ("\teor %5, %0, %1\n"
+      "\tmovs %4, %0\n"
+      "\trsbmi %0, %0, #0 \n"
+      "\tmovs %4, %1\n"
+      "\trsbmi %1, %1, #0 \n"
+      "\tmov %4, #1\n"
+      "\tsubs %3, %0, %1, asl #14 \n"
+      "\tmovpl %0, %3 \n"
+      "\torrpl %2, %2, %4, asl #14 \n"
+      "\tsubs %3, %0, %1, asl #13 \n"
+      "\tmovpl %0, %3 \n"
+      "\torrpl %2, %2, %4, asl #13 \n"
+      "\tsubs %3, %0, %1, asl #12 \n"
+      "\tmovpl %0, %3 \n"
+      "\torrpl %2, %2, %4, asl #12 \n"
+      "\tsubs %3, %0, %1, asl #11 \n"
+      "\tmovpl %0, %3 \n"
+      "\torrpl %2, %2, %4, asl #11 \n"
+      "\tsubs %3, %0, %1, asl #10 \n"
+      "\tmovpl %0, %3 \n"
+      "\torrpl %2, %2, %4, asl #10 \n"
+      "\tsubs %3, %0, %1, asl #9 \n"
+      "\tmovpl %0, %3 \n"
+      "\torrpl %2, %2, %4, asl #9 \n"
+      "\tsubs %3, %0, %1, asl #8 \n"
+      "\tmovpl %0, %3 \n"
+      "\torrpl %2, %2, %4, asl #8 \n"
+      "\tsubs %3, %0, %1, asl #7 \n"
+      "\tmovpl %0, %3 \n"
+      "\torrpl %2, %2, %4, asl #7 \n"
+      "\tsubs %3, %0, %1, asl #6 \n"
+      "\tmovpl %0, %3 \n"
+      "\torrpl %2, %2, %4, asl #6 \n"
+      "\tsubs %3, %0, %1, asl #5 \n"
+      "\tmovpl %0, %3 \n"
+      "\torrpl %2, %2, %4, asl #5 \n"
+      "\tsubs %3, %0, %1, asl #4 \n"
+      "\tmovpl %0, %3 \n"
+      "\torrpl %2, %2, %4, asl #4 \n"
+      "\tsubs %3, %0, %1, asl #3 \n"
+      "\tmovpl %0, %3 \n"
+      "\torrpl %2, %2, %4, asl #3 \n"
+      "\tsubs %3, %0, %1, asl #2 \n"
+      "\tmovpl %0, %3 \n"
+      "\torrpl %2, %2, %4, asl #2 \n"
+      "\tsubs %3, %0, %1, asl #1 \n"
+      "\tmovpl %0, %3 \n"
+      "\torrpl %2, %2, %4, asl #1 \n"
+      "\tsubs %3, %0, %1 \n"
+      "\tmovpl %0, %3 \n"
+      "\torrpl %2, %2, %4 \n"
+      "\tmovs %5, %5, lsr #31 \n"
+      "\trsbne %2, %2, #0 \n":"=r" (dead1), "=r" (dead2), "=r" (res),
+      "=r" (dead3), "=r" (dead4), "=r" (dead5)
+      :"0" (a), "1" (b), "2" (res)
+      :"cc");
+  return res;
+}
+
+
+#endif
diff --git a/gst/speexresample/fixed_arm5e.h b/gst/speexresample/fixed_arm5e.h
new file mode 100644 (file)
index 0000000..c995d54
--- /dev/null
@@ -0,0 +1,166 @@
+/* Copyright (C) 2003 Jean-Marc Valin */
+/**
+   @file fixed_arm5e.h
+   @brief ARM-tuned fixed-point operations
+*/
+/*
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
+   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef FIXED_ARM5E_H
+#define FIXED_ARM5E_H
+
+#undef MULT16_16
+static inline spx_word32_t
+MULT16_16 (spx_word16_t x, spx_word16_t y)
+{
+  int res;
+asm ("smulbb  %0,%1,%2;\n":"=&r" (res)
+:    "%r" (x), "r" (y));
+  return (res);
+}
+
+#undef MAC16_16
+static inline spx_word32_t
+MAC16_16 (spx_word32_t a, spx_word16_t x, spx_word32_t y)
+{
+  int res;
+asm ("smlabb  %0,%1,%2,%3;\n":"=&r" (res)
+:    "%r" (x), "r" (y), "r" (a));
+  return (res);
+}
+
+#undef MULT16_32_Q15
+static inline spx_word32_t
+MULT16_32_Q15 (spx_word16_t x, spx_word32_t y)
+{
+  int res;
+asm ("smulwb  %0,%1,%2;\n":"=&r" (res)
+:    "%r" (y << 1), "r" (x));
+  return (res);
+}
+
+#undef MAC16_32_Q15
+static inline spx_word32_t
+MAC16_32_Q15 (spx_word32_t a, spx_word16_t x, spx_word32_t y)
+{
+  int res;
+asm ("smlawb  %0,%1,%2,%3;\n":"=&r" (res)
+:    "%r" (y << 1), "r" (x), "r" (a));
+  return (res);
+}
+
+#undef MULT16_32_Q11
+static inline spx_word32_t
+MULT16_32_Q11 (spx_word16_t x, spx_word32_t y)
+{
+  int res;
+asm ("smulwb  %0,%1,%2;\n":"=&r" (res)
+:    "%r" (y << 5), "r" (x));
+  return (res);
+}
+
+#undef MAC16_32_Q11
+static inline spx_word32_t
+MAC16_32_Q11 (spx_word32_t a, spx_word16_t x, spx_word32_t y)
+{
+  int res;
+asm ("smlawb  %0,%1,%2,%3;\n":"=&r" (res)
+:    "%r" (y << 5), "r" (x), "r" (a));
+  return (res);
+}
+
+#undef DIV32_16
+static inline short
+DIV32_16 (int a, int b)
+{
+  int res = 0;
+  int dead1, dead2, dead3, dead4, dead5;
+  __asm__ __volatile__ ("\teor %5, %0, %1\n"
+      "\tmovs %4, %0\n"
+      "\trsbmi %0, %0, #0 \n"
+      "\tmovs %4, %1\n"
+      "\trsbmi %1, %1, #0 \n"
+      "\tmov %4, #1\n"
+      "\tsubs %3, %0, %1, asl #14 \n"
+      "\torrpl %2, %2, %4, asl #14 \n"
+      "\tmovpl %0, %3 \n"
+      "\tsubs %3, %0, %1, asl #13 \n"
+      "\torrpl %2, %2, %4, asl #13 \n"
+      "\tmovpl %0, %3 \n"
+      "\tsubs %3, %0, %1, asl #12 \n"
+      "\torrpl %2, %2, %4, asl #12 \n"
+      "\tmovpl %0, %3 \n"
+      "\tsubs %3, %0, %1, asl #11 \n"
+      "\torrpl %2, %2, %4, asl #11 \n"
+      "\tmovpl %0, %3 \n"
+      "\tsubs %3, %0, %1, asl #10 \n"
+      "\torrpl %2, %2, %4, asl #10 \n"
+      "\tmovpl %0, %3 \n"
+      "\tsubs %3, %0, %1, asl #9 \n"
+      "\torrpl %2, %2, %4, asl #9 \n"
+      "\tmovpl %0, %3 \n"
+      "\tsubs %3, %0, %1, asl #8 \n"
+      "\torrpl %2, %2, %4, asl #8 \n"
+      "\tmovpl %0, %3 \n"
+      "\tsubs %3, %0, %1, asl #7 \n"
+      "\torrpl %2, %2, %4, asl #7 \n"
+      "\tmovpl %0, %3 \n"
+      "\tsubs %3, %0, %1, asl #6 \n"
+      "\torrpl %2, %2, %4, asl #6 \n"
+      "\tmovpl %0, %3 \n"
+      "\tsubs %3, %0, %1, asl #5 \n"
+      "\torrpl %2, %2, %4, asl #5 \n"
+      "\tmovpl %0, %3 \n"
+      "\tsubs %3, %0, %1, asl #4 \n"
+      "\torrpl %2, %2, %4, asl #4 \n"
+      "\tmovpl %0, %3 \n"
+      "\tsubs %3, %0, %1, asl #3 \n"
+      "\torrpl %2, %2, %4, asl #3 \n"
+      "\tmovpl %0, %3 \n"
+      "\tsubs %3, %0, %1, asl #2 \n"
+      "\torrpl %2, %2, %4, asl #2 \n"
+      "\tmovpl %0, %3 \n"
+      "\tsubs %3, %0, %1, asl #1 \n"
+      "\torrpl %2, %2, %4, asl #1 \n"
+      "\tmovpl %0, %3 \n"
+      "\tsubs %3, %0, %1 \n"
+      "\torrpl %2, %2, %4 \n"
+      "\tmovpl %0, %3 \n"
+      "\tmovs %5, %5, lsr #31 \n"
+      "\trsbne %2, %2, #0 \n":"=r" (dead1), "=r" (dead2), "=r" (res),
+      "=r" (dead3), "=r" (dead4), "=r" (dead5)
+      :"0" (a), "1" (b), "2" (res)
+      :"memory", "cc");
+  return res;
+}
+
+
+
+
+#endif
diff --git a/gst/speexresample/fixed_bfin.h b/gst/speexresample/fixed_bfin.h
new file mode 100644 (file)
index 0000000..63b3fb4
--- /dev/null
@@ -0,0 +1,134 @@
+/* Copyright (C) 2005 Analog Devices
+   Author: Jean-Marc Valin */
+/**
+   @file fixed_bfin.h
+   @brief Blackfin fixed-point operations
+*/
+/*
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
+   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef FIXED_BFIN_H
+#define FIXED_BFIN_H
+
+#undef PDIV32_16
+static inline spx_word16_t
+PDIV32_16 (spx_word32_t a, spx_word16_t b)
+{
+  spx_word32_t res, bb;
+  bb = b;
+  a += b >> 1;
+  __asm__ ("P0 = 15;\n\t" "R0 = %1;\n\t" "R1 = %2;\n\t"
+      //"R0 = R0 + R1;\n\t"
+"R0 <<= 1;\n\t" "DIVS (R0, R1);\n\t" "LOOP divide%= LC0 = P0;\n\t" "LOOP_BEGIN divide%=;\n\t" "DIVQ (R0, R1);\n\t" "LOOP_END divide%=;\n\t" "R0 = R0.L;\n\t" "%0 = R0;\n\t":"=m"
+      (res)
+:    "m" (a), "m" (bb)
+:    "P0", "R0", "R1", "cc");
+  return res;
+}
+
+#undef DIV32_16
+static inline spx_word16_t
+DIV32_16 (spx_word32_t a, spx_word16_t b)
+{
+  spx_word32_t res, bb;
+  bb = b;
+  /* Make the roundinf consistent with the C version 
+     (do we need to do that?) */
+  if (a < 0)
+    a += (b - 1);
+__asm__ ("P0 = 15;\n\t" "R0 = %1;\n\t" "R1 = %2;\n\t" "R0 <<= 1;\n\t" "DIVS (R0, R1);\n\t" "LOOP divide%= LC0 = P0;\n\t" "LOOP_BEGIN divide%=;\n\t" "DIVQ (R0, R1);\n\t" "LOOP_END divide%=;\n\t" "R0 = R0.L;\n\t" "%0 = R0;\n\t":"=m" (res)
+:    "m" (a), "m" (bb)
+:    "P0", "R0", "R1", "cc");
+  return res;
+}
+
+#undef MAX16
+static inline spx_word16_t
+MAX16 (spx_word16_t a, spx_word16_t b)
+{
+  spx_word32_t res;
+__asm__ ("%1 = %1.L (X);\n\t" "%2 = %2.L (X);\n\t" "%0 = MAX(%1,%2);":"=d" (res)
+:    "%d" (a), "d" (b)
+      );
+  return res;
+}
+
+#undef MULT16_32_Q15
+static inline spx_word32_t
+MULT16_32_Q15 (spx_word16_t a, spx_word32_t b)
+{
+  spx_word32_t res;
+__asm__ ("A1 = %2.L*%1.L (M);\n\t" "A1 = A1 >>> 15;\n\t" "%0 = (A1 += %2.L*%1.H) ;\n\t":"=&W" (res),
+      "=&d"
+      (b)
+:    "d" (a), "1" (b)
+:    "A1");
+  return res;
+}
+
+#undef MAC16_32_Q15
+static inline spx_word32_t
+MAC16_32_Q15 (spx_word32_t c, spx_word16_t a, spx_word32_t b)
+{
+  spx_word32_t res;
+__asm__ ("A1 = %2.L*%1.L (M);\n\t" "A1 = A1 >>> 15;\n\t" "%0 = (A1 += %2.L*%1.H);\n\t" "%0 = %0 + %4;\n\t":"=&W" (res),
+      "=&d"
+      (b)
+:    "d" (a), "1" (b), "d" (c)
+:    "A1");
+  return res;
+}
+
+#undef MULT16_32_Q14
+static inline spx_word32_t
+MULT16_32_Q14 (spx_word16_t a, spx_word32_t b)
+{
+  spx_word32_t res;
+__asm__ ("%2 <<= 1;\n\t" "A1 = %1.L*%2.L (M);\n\t" "A1 = A1 >>> 15;\n\t" "%0 = (A1 += %1.L*%2.H);\n\t":"=W" (res), "=d" (a),
+      "=d"
+      (b)
+:    "1" (a), "2" (b)
+:    "A1");
+  return res;
+}
+
+#undef MAC16_32_Q14
+static inline spx_word32_t
+MAC16_32_Q14 (spx_word32_t c, spx_word16_t a, spx_word32_t b)
+{
+  spx_word32_t res;
+__asm__ ("%1 <<= 1;\n\t" "A1 = %2.L*%1.L (M);\n\t" "A1 = A1 >>> 15;\n\t" "%0 = (A1 += %2.L*%1.H);\n\t" "%0 = %0 + %4;\n\t":"=&W" (res),
+      "=&d"
+      (b)
+:    "d" (a), "1" (b), "d" (c)
+:    "A1");
+  return res;
+}
+
+#endif
diff --git a/gst/speexresample/fixed_debug.h b/gst/speexresample/fixed_debug.h
new file mode 100644 (file)
index 0000000..9ee8fa2
--- /dev/null
@@ -0,0 +1,525 @@
+/* Copyright (C) 2003 Jean-Marc Valin */
+/**
+   @file fixed_debug.h
+   @brief Fixed-point operations with debugging
+*/
+/*
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
+   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef FIXED_DEBUG_H
+#define FIXED_DEBUG_H
+
+#include <stdio.h>
+
+extern long long spx_mips;
+#define MIPS_INC spx_mips++,
+
+#define QCONST16(x,bits) ((spx_word16_t)(.5+(x)*(((spx_word32_t)1)<<(bits))))
+#define QCONST32(x,bits) ((spx_word32_t)(.5+(x)*(((spx_word32_t)1)<<(bits))))
+
+
+#define VERIFY_SHORT(x) ((x)<=32767&&(x)>=-32768)
+#define VERIFY_INT(x) ((x)<=2147483647LL&&(x)>=-2147483648LL)
+
+static inline short
+NEG16 (int x)
+{
+  int res;
+  if (!VERIFY_SHORT (x)) {
+    fprintf (stderr, "NEG16: input is not short: %d\n", (int) x);
+  }
+  res = -x;
+  if (!VERIFY_SHORT (res))
+    fprintf (stderr, "NEG16: output is not short: %d\n", (int) res);
+  spx_mips++;
+  return res;
+}
+
+static inline int
+NEG32 (long long x)
+{
+  long long res;
+  if (!VERIFY_INT (x)) {
+    fprintf (stderr, "NEG16: input is not int: %d\n", (int) x);
+  }
+  res = -x;
+  if (!VERIFY_INT (res))
+    fprintf (stderr, "NEG16: output is not int: %d\n", (int) res);
+  spx_mips++;
+  return res;
+}
+
+#define EXTRACT16(x) _EXTRACT16(x, __FILE__, __LINE__)
+static inline short
+_EXTRACT16 (int x, char *file, int line)
+{
+  int res;
+  if (!VERIFY_SHORT (x)) {
+    fprintf (stderr, "EXTRACT16: input is not short: %d in %s: line %d\n", x,
+        file, line);
+  }
+  res = x;
+  spx_mips++;
+  return res;
+}
+
+#define EXTEND32(x) _EXTEND32(x, __FILE__, __LINE__)
+static inline int
+_EXTEND32 (int x, char *file, int line)
+{
+  int res;
+  if (!VERIFY_SHORT (x)) {
+    fprintf (stderr, "EXTEND32: input is not short: %d in %s: line %d\n", x,
+        file, line);
+  }
+  res = x;
+  spx_mips++;
+  return res;
+}
+
+#define SHR16(a, shift) _SHR16(a, shift, __FILE__, __LINE__)
+static inline short
+_SHR16 (int a, int shift, char *file, int line)
+{
+  int res;
+  if (!VERIFY_SHORT (a) || !VERIFY_SHORT (shift)) {
+    fprintf (stderr, "SHR16: inputs are not short: %d >> %d in %s: line %d\n",
+        a, shift, file, line);
+  }
+  res = a >> shift;
+  if (!VERIFY_SHORT (res))
+    fprintf (stderr, "SHR16: output is not short: %d in %s: line %d\n", res,
+        file, line);
+  spx_mips++;
+  return res;
+}
+
+#define SHL16(a, shift) _SHL16(a, shift, __FILE__, __LINE__)
+static inline short
+_SHL16 (int a, int shift, char *file, int line)
+{
+  int res;
+  if (!VERIFY_SHORT (a) || !VERIFY_SHORT (shift)) {
+    fprintf (stderr, "SHL16: inputs are not short: %d %d in %s: line %d\n", a,
+        shift, file, line);
+  }
+  res = a << shift;
+  if (!VERIFY_SHORT (res))
+    fprintf (stderr, "SHL16: output is not short: %d in %s: line %d\n", res,
+        file, line);
+  spx_mips++;
+  return res;
+}
+
+static inline int
+SHR32 (long long a, int shift)
+{
+  long long res;
+  if (!VERIFY_INT (a) || !VERIFY_SHORT (shift)) {
+    fprintf (stderr, "SHR32: inputs are not int: %d %d\n", (int) a, shift);
+  }
+  res = a >> shift;
+  if (!VERIFY_INT (res)) {
+    fprintf (stderr, "SHR32: output is not int: %d\n", (int) res);
+  }
+  spx_mips++;
+  return res;
+}
+
+static inline int
+SHL32 (long long a, int shift)
+{
+  long long res;
+  if (!VERIFY_INT (a) || !VERIFY_SHORT (shift)) {
+    fprintf (stderr, "SHL32: inputs are not int: %d %d\n", (int) a, shift);
+  }
+  res = a << shift;
+  if (!VERIFY_INT (res)) {
+    fprintf (stderr, "SHL32: output is not int: %d\n", (int) res);
+  }
+  spx_mips++;
+  return res;
+}
+
+#define PSHR16(a,shift) (SHR16(ADD16((a),((1<<((shift))>>1))),shift))
+#define PSHR32(a,shift) (SHR32(ADD32((a),((EXTEND32(1)<<((shift))>>1))),shift))
+#define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift)))
+
+#define SATURATE16(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
+#define SATURATE32(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
+
+//#define SHR(a,shift) ((a) >> (shift))
+//#define SHL(a,shift) ((a) << (shift))
+
+#define ADD16(a, b) _ADD16(a, b, __FILE__, __LINE__)
+static inline short
+_ADD16 (int a, int b, char *file, int line)
+{
+  int res;
+  if (!VERIFY_SHORT (a) || !VERIFY_SHORT (b)) {
+    fprintf (stderr, "ADD16: inputs are not short: %d %d in %s: line %d\n", a,
+        b, file, line);
+  }
+  res = a + b;
+  if (!VERIFY_SHORT (res)) {
+    fprintf (stderr, "ADD16: output is not short: %d+%d=%d in %s: line %d\n", a,
+        b, res, file, line);
+  }
+  spx_mips++;
+  return res;
+}
+
+#define SUB16(a, b) _SUB16(a, b, __FILE__, __LINE__)
+static inline short
+_SUB16 (int a, int b, char *file, int line)
+{
+  int res;
+  if (!VERIFY_SHORT (a) || !VERIFY_SHORT (b)) {
+    fprintf (stderr, "SUB16: inputs are not short: %d %d in %s: line %d\n", a,
+        b, file, line);
+  }
+  res = a - b;
+  if (!VERIFY_SHORT (res))
+    fprintf (stderr, "SUB16: output is not short: %d in %s: line %d\n", res,
+        file, line);
+  spx_mips++;
+  return res;
+}
+
+#define ADD32(a, b) _ADD32(a, b, __FILE__, __LINE__)
+static inline int
+_ADD32 (long long a, long long b, char *file, int line)
+{
+  long long res;
+  if (!VERIFY_INT (a) || !VERIFY_INT (b)) {
+    fprintf (stderr, "ADD32: inputs are not int: %d %d in %s: line %d\n",
+        (int) a, (int) b, file, line);
+  }
+  res = a + b;
+  if (!VERIFY_INT (res)) {
+    fprintf (stderr, "ADD32: output is not int: %d in %s: line %d\n", (int) res,
+        file, line);
+  }
+  spx_mips++;
+  return res;
+}
+
+static inline int
+SUB32 (long long a, long long b)
+{
+  long long res;
+  if (!VERIFY_INT (a) || !VERIFY_INT (b)) {
+    fprintf (stderr, "SUB32: inputs are not int: %d %d\n", (int) a, (int) b);
+  }
+  res = a - b;
+  if (!VERIFY_INT (res))
+    fprintf (stderr, "SUB32: output is not int: %d\n", (int) res);
+  spx_mips++;
+  return res;
+}
+
+#define ADD64(a,b) (MIPS_INC(a)+(b))
+
+/* result fits in 16 bits */
+static inline short
+MULT16_16_16 (int a, int b)
+{
+  int res;
+  if (!VERIFY_SHORT (a) || !VERIFY_SHORT (b)) {
+    fprintf (stderr, "MULT16_16_16: inputs are not short: %d %d\n", a, b);
+  }
+  res = a * b;
+  if (!VERIFY_SHORT (res))
+    fprintf (stderr, "MULT16_16_16: output is not short: %d\n", res);
+  spx_mips++;
+  return res;
+}
+
+#define MULT16_16(a, b) _MULT16_16(a, b, __FILE__, __LINE__)
+static inline int
+_MULT16_16 (int a, int b, char *file, int line)
+{
+  long long res;
+  if (!VERIFY_SHORT (a) || !VERIFY_SHORT (b)) {
+    fprintf (stderr, "MULT16_16: inputs are not short: %d %d in %s: line %d\n",
+        a, b, file, line);
+  }
+  res = ((long long) a) * b;
+  if (!VERIFY_INT (res))
+    fprintf (stderr, "MULT16_16: output is not int: %d in %s: line %d\n",
+        (int) res, file, line);
+  spx_mips++;
+  return res;
+}
+
+#define MAC16_16(c,a,b)     (spx_mips--,ADD32((c),MULT16_16((a),(b))))
+#define MAC16_16_Q11(c,a,b)     (EXTRACT16(ADD16((c),EXTRACT16(SHR32(MULT16_16((a),(b)),11)))))
+#define MAC16_16_Q13(c,a,b)     (EXTRACT16(ADD16((c),EXTRACT16(SHR32(MULT16_16((a),(b)),13)))))
+#define MAC16_16_P13(c,a,b)     (EXTRACT16(ADD32((c),SHR32(ADD32(4096,MULT16_16((a),(b))),13))))
+
+
+#define MULT16_32_QX(a, b, Q) _MULT16_32_QX(a, b, Q, __FILE__, __LINE__)
+static inline int
+_MULT16_32_QX (int a, long long b, int Q, char *file, int line)
+{
+  long long res;
+  if (!VERIFY_SHORT (a) || !VERIFY_INT (b)) {
+    fprintf (stderr,
+        "MULT16_32_Q%d: inputs are not short+int: %d %d in %s: line %d\n", Q,
+        (int) a, (int) b, file, line);
+  }
+  if (ABS32 (b) >= (EXTEND32 (1) << (15 + Q)))
+    fprintf (stderr,
+        "MULT16_32_Q%d: second operand too large: %d %d in %s: line %d\n", Q,
+        (int) a, (int) b, file, line);
+  res = (((long long) a) * (long long) b) >> Q;
+  if (!VERIFY_INT (res))
+    fprintf (stderr,
+        "MULT16_32_Q%d: output is not int: %d*%d=%d in %s: line %d\n", Q,
+        (int) a, (int) b, (int) res, file, line);
+  spx_mips += 5;
+  return res;
+}
+
+static inline int
+MULT16_32_PX (int a, long long b, int Q)
+{
+  long long res;
+  if (!VERIFY_SHORT (a) || !VERIFY_INT (b)) {
+    fprintf (stderr, "MULT16_32_P%d: inputs are not short+int: %d %d\n", Q,
+        (int) a, (int) b);
+  }
+  if (ABS32 (b) >= (EXTEND32 (1) << (15 + Q)))
+    fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d\n", Q,
+        (int) a, (int) b);
+  res = ((((long long) a) * (long long) b) + ((EXTEND32 (1) << Q) >> 1)) >> Q;
+  if (!VERIFY_INT (res))
+    fprintf (stderr, "MULT16_32_P%d: output is not int: %d*%d=%d\n", Q, (int) a,
+        (int) b, (int) res);
+  spx_mips += 5;
+  return res;
+}
+
+
+#define MULT16_32_Q11(a,b) MULT16_32_QX(a,b,11)
+#define MAC16_32_Q11(c,a,b) ADD32((c),MULT16_32_Q11((a),(b)))
+#define MULT16_32_Q12(a,b) MULT16_32_QX(a,b,12)
+#define MULT16_32_Q13(a,b) MULT16_32_QX(a,b,13)
+#define MULT16_32_Q14(a,b) MULT16_32_QX(a,b,14)
+#define MULT16_32_Q15(a,b) MULT16_32_QX(a,b,15)
+#define MULT16_32_P15(a,b) MULT16_32_PX(a,b,15)
+#define MAC16_32_Q15(c,a,b) ADD32((c),MULT16_32_Q15((a),(b)))
+
+static inline int
+SATURATE (int a, int b)
+{
+  if (a > b)
+    a = b;
+  if (a < -b)
+    a = -b;
+  return a;
+}
+
+static inline int
+MULT16_16_Q11_32 (int a, int b)
+{
+  long long res;
+  if (!VERIFY_SHORT (a) || !VERIFY_SHORT (b)) {
+    fprintf (stderr, "MULT16_16_Q11: inputs are not short: %d %d\n", a, b);
+  }
+  res = ((long long) a) * b;
+  res >>= 11;
+  if (!VERIFY_INT (res))
+    fprintf (stderr, "MULT16_16_Q11: output is not short: %d*%d=%d\n", (int) a,
+        (int) b, (int) res);
+  spx_mips += 3;
+  return res;
+}
+
+static inline short
+MULT16_16_Q13 (int a, int b)
+{
+  long long res;
+  if (!VERIFY_SHORT (a) || !VERIFY_SHORT (b)) {
+    fprintf (stderr, "MULT16_16_Q13: inputs are not short: %d %d\n", a, b);
+  }
+  res = ((long long) a) * b;
+  res >>= 13;
+  if (!VERIFY_SHORT (res))
+    fprintf (stderr, "MULT16_16_Q13: output is not short: %d*%d=%d\n", a, b,
+        (int) res);
+  spx_mips += 3;
+  return res;
+}
+
+static inline short
+MULT16_16_Q14 (int a, int b)
+{
+  long long res;
+  if (!VERIFY_SHORT (a) || !VERIFY_SHORT (b)) {
+    fprintf (stderr, "MULT16_16_Q14: inputs are not short: %d %d\n", a, b);
+  }
+  res = ((long long) a) * b;
+  res >>= 14;
+  if (!VERIFY_SHORT (res))
+    fprintf (stderr, "MULT16_16_Q14: output is not short: %d\n", (int) res);
+  spx_mips += 3;
+  return res;
+}
+
+static inline short
+MULT16_16_Q15 (int a, int b)
+{
+  long long res;
+  if (!VERIFY_SHORT (a) || !VERIFY_SHORT (b)) {
+    fprintf (stderr, "MULT16_16_Q15: inputs are not short: %d %d\n", a, b);
+  }
+  res = ((long long) a) * b;
+  res >>= 15;
+  if (!VERIFY_SHORT (res)) {
+    fprintf (stderr, "MULT16_16_Q15: output is not short: %d\n", (int) res);
+  }
+  spx_mips += 3;
+  return res;
+}
+
+static inline short
+MULT16_16_P13 (int a, int b)
+{
+  long long res;
+  if (!VERIFY_SHORT (a) || !VERIFY_SHORT (b)) {
+    fprintf (stderr, "MULT16_16_P13: inputs are not short: %d %d\n", a, b);
+  }
+  res = ((long long) a) * b;
+  res += 4096;
+  if (!VERIFY_INT (res))
+    fprintf (stderr, "MULT16_16_P13: overflow: %d*%d=%d\n", a, b, (int) res);
+  res >>= 13;
+  if (!VERIFY_SHORT (res))
+    fprintf (stderr, "MULT16_16_P13: output is not short: %d*%d=%d\n", a, b,
+        (int) res);
+  spx_mips += 4;
+  return res;
+}
+
+static inline short
+MULT16_16_P14 (int a, int b)
+{
+  long long res;
+  if (!VERIFY_SHORT (a) || !VERIFY_SHORT (b)) {
+    fprintf (stderr, "MULT16_16_P14: inputs are not short: %d %d\n", a, b);
+  }
+  res = ((long long) a) * b;
+  res += 8192;
+  if (!VERIFY_INT (res))
+    fprintf (stderr, "MULT16_16_P14: overflow: %d*%d=%d\n", a, b, (int) res);
+  res >>= 14;
+  if (!VERIFY_SHORT (res))
+    fprintf (stderr, "MULT16_16_P14: output is not short: %d*%d=%d\n", a, b,
+        (int) res);
+  spx_mips += 4;
+  return res;
+}
+
+static inline short
+MULT16_16_P15 (int a, int b)
+{
+  long long res;
+  if (!VERIFY_SHORT (a) || !VERIFY_SHORT (b)) {
+    fprintf (stderr, "MULT16_16_P15: inputs are not short: %d %d\n", a, b);
+  }
+  res = ((long long) a) * b;
+  res += 16384;
+  if (!VERIFY_INT (res))
+    fprintf (stderr, "MULT16_16_P15: overflow: %d*%d=%d\n", a, b, (int) res);
+  res >>= 15;
+  if (!VERIFY_SHORT (res))
+    fprintf (stderr, "MULT16_16_P15: output is not short: %d*%d=%d\n", a, b,
+        (int) res);
+  spx_mips += 4;
+  return res;
+}
+
+#define DIV32_16(a, b) _DIV32_16(a, b, __FILE__, __LINE__)
+
+static inline int
+_DIV32_16 (long long a, long long b, char *file, int line)
+{
+  long long res;
+  if (b == 0) {
+    fprintf (stderr, "DIV32_16: divide by zero: %d/%d in %s: line %d\n",
+        (int) a, (int) b, file, line);
+    return 0;
+  }
+  if (!VERIFY_INT (a) || !VERIFY_SHORT (b)) {
+    fprintf (stderr,
+        "DIV32_16: inputs are not int/short: %d %d in %s: line %d\n", (int) a,
+        (int) b, file, line);
+  }
+  res = a / b;
+  if (!VERIFY_SHORT (res)) {
+    fprintf (stderr,
+        "DIV32_16: output is not short: %d / %d = %d in %s: line %d\n", (int) a,
+        (int) b, (int) res, file, line);
+    if (res > 32767)
+      res = 32767;
+    if (res < -32768)
+      res = -32768;
+  }
+  spx_mips += 20;
+  return res;
+}
+
+#define DIV32(a, b) _DIV32(a, b, __FILE__, __LINE__)
+static inline int
+_DIV32 (long long a, long long b, char *file, int line)
+{
+  long long res;
+  if (b == 0) {
+    fprintf (stderr, "DIV32: divide by zero: %d/%d in %s: line %d\n", (int) a,
+        (int) b, file, line);
+    return 0;
+  }
+
+  if (!VERIFY_INT (a) || !VERIFY_INT (b)) {
+    fprintf (stderr, "DIV32: inputs are not int/short: %d %d in %s: line %d\n",
+        (int) a, (int) b, file, line);
+  }
+  res = a / b;
+  if (!VERIFY_INT (res))
+    fprintf (stderr, "DIV32: output is not int: %d in %s: line %d\n", (int) res,
+        file, line);
+  spx_mips += 36;
+  return res;
+}
+
+#define PDIV32(a,b) DIV32(ADD32((a),(b)>>1),b)
+#define PDIV32_16(a,b) DIV32_16(ADD32((a),(b)>>1),b)
+
+#endif
index 2948177..3fb096e 100644 (file)
 #define SHR32(a,shift) ((a) >> (shift))
 #define SHL32(a,shift) ((a) << (shift))
 #define PSHR16(a,shift) (SHR16((a)+((1<<((shift))>>1)),shift))
-#define PSHR32(a,shift) (SHR32((a)+((1<<((shift))>>1)),shift))
+#define PSHR32(a,shift) (SHR32((a)+((EXTEND32(1)<<((shift))>>1)),shift))
 #define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift)))
 #define SATURATE16(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
 #define SATURATE32(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
 
 #define SHR(a,shift) ((a) >> (shift))
 #define SHL(a,shift) ((spx_word32_t)(a) << (shift))
-#define PSHR(a,shift) (SHR((a)+((1<<((shift))>>1)),shift))
+#define PSHR(a,shift) (SHR((a)+((EXTEND32(1)<<((shift))>>1)),shift))
 #define SATURATE(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
 
 
index 29b95f2..ec127aa 100644 (file)
@@ -1,4 +1,5 @@
-/* Copyright (C) 2007 Jean-Marc Valin
+/* Copyright (C) 2007-2008 Jean-Marc Valin
+   Copyright (C) 2008      Thorvald Natvig
       
    File: resample.c
    Arbitrary resampling code
 
 #ifdef OUTSIDE_SPEEX
 #include <stdlib.h>
+
 #include <glib.h>
 
+#define EXPORT
+
 static inline void *
 speex_alloc (int size)
 {
   return g_malloc0 (size);
 }
+
 static inline void *
 speex_realloc (void *ptr, int size)
 {
@@ -85,7 +90,7 @@ speex_free (void *ptr)
 #include "arch.h"
 #else /* OUTSIDE_SPEEX */
 
-#include "speex/speex_resampler.h"
+#include "../include/speex/speex_resampler.h"
 #include "arch.h"
 #include "os_support.h"
 #endif /* OUTSIDE_SPEEX */
@@ -102,10 +107,6 @@ speex_free (void *ptr)
 #define WORD2INT(x) ((x) < -32767.5f ? -32768 : ((x) > 32766.5f ? 32767 : floor(.5+(x))))
 #endif
 
-/*#define float double*/
-#define FILTER_SIZE 64
-#define OVERSAMPLE 8
-
 #define IMAX(a,b) ((a) > (b) ? (a) : (b))
 #define IMIN(a,b) ((a) < (b) ? (a) : (b))
 
@@ -113,6 +114,17 @@ speex_free (void *ptr)
 #define NULL 0
 #endif
 
+#ifdef _USE_SSE
+#include "resample_sse.h"
+#endif
+
+/* Numer of elements to allocate on the stack */
+#ifdef VAR_ARRAYS
+#define FIXED_STACK_ALLOC 8192
+#else
+#define FIXED_STACK_ALLOC 1024
+#endif
+
 typedef int (*resampler_basic_func) (SpeexResamplerState *, spx_uint32_t,
     const spx_word16_t *, spx_uint32_t *, spx_word16_t *, spx_uint32_t *);
 
@@ -127,6 +139,7 @@ struct SpeexResamplerState_
   spx_uint32_t nb_channels;
   spx_uint32_t filt_len;
   spx_uint32_t mem_alloc_size;
+  spx_uint32_t buffer_size;
   int int_advance;
   int frac_advance;
   float cutoff;
@@ -260,7 +273,6 @@ compute_func (float x, struct FuncDef *func)
   float y, frac;
   double interp[4];
   int ind;
-
   y = x * func->oversample;
   ind = (int) floor (y);
   frac = (y - ind);
@@ -285,7 +297,6 @@ int
 main (int argc, char **argv)
 {
   int i;
-
   for (i = 0; i < 256; i++) {
     printf ("%f\n", compute_func (i / 256., KAISER12));
   }
@@ -300,7 +311,6 @@ sinc (float cutoff, float x, int N, struct FuncDef *window_func)
 {
   /*fprintf (stderr, "%f ", x); */
   float xx = x * cutoff;
-
   if (fabs (x) < 1e-6f)
     return WORD2INT (32768. * cutoff);
   else if (fabs (x) > .5f * N)
@@ -316,7 +326,6 @@ sinc (float cutoff, float x, int N, struct FuncDef *window_func)
 {
   /*fprintf (stderr, "%f ", x); */
   float xx = x * cutoff;
-
   if (fabs (x) < 1e-6)
     return cutoff;
   else if (fabs (x) > .5 * N)
@@ -334,7 +343,6 @@ cubic_coef (spx_word16_t x, spx_word16_t interp[4])
   /* Compute interpolation coefficients. I'm not sure whether this corresponds to cubic interpolation
      but I know it's MMSE-optimal on a sinc */
   spx_word16_t x2, x3;
-
   x2 = MULT16_16_P15 (x, x);
   x3 = MULT16_16_P15 (x, x2);
   interp[0] =
@@ -373,48 +381,46 @@ resampler_basic_direct_single (SpeexResamplerState * st,
     spx_uint32_t channel_index, const spx_word16_t * in, spx_uint32_t * in_len,
     spx_word16_t * out, spx_uint32_t * out_len)
 {
-  int N = st->filt_len;
+  const int N = st->filt_len;
   int out_sample = 0;
-  spx_word16_t *mem;
   int last_sample = st->last_sample[channel_index];
   spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index];
+  const spx_word16_t *sinc_table = st->sinc_table;
+  const int out_stride = st->out_stride;
+  const int int_advance = st->int_advance;
+  const int frac_advance = st->frac_advance;
+  const spx_uint32_t den_rate = st->den_rate;
+  spx_word32_t sum;
+  int j;
 
-  mem = st->mem + channel_index * st->mem_alloc_size;
   while (!(last_sample >= (spx_int32_t) * in_len
           || out_sample >= (spx_int32_t) * out_len)) {
-    int j;
-    spx_word32_t sum = 0;
-
-    /* We already have all the filter coefficients pre-computed in the table */
-    const spx_word16_t *ptr;
+    const spx_word16_t *sinc = &sinc_table[samp_frac_num * N];
+    const spx_word16_t *iptr = &in[last_sample];
 
-    /* Do the memory part */
-    for (j = 0; last_sample - N + 1 + j < 0; j++) {
-      sum +=
-          MULT16_16 (mem[last_sample + j],
-          st->sinc_table[samp_frac_num * st->filt_len + j]);
-    }
+#ifndef OVERRIDE_INNER_PRODUCT_SINGLE
+    float accum[4] = { 0, 0, 0, 0 };
 
-    /* Do the new part */
-    if (in != NULL) {
-      ptr = in + st->in_stride * (last_sample - N + 1 + j);
-      for (; j < N; j++) {
-        sum +=
-            MULT16_16 (*ptr, st->sinc_table[samp_frac_num * st->filt_len + j]);
-        ptr += st->in_stride;
-      }
+    for (j = 0; j < N; j += 4) {
+      accum[0] += sinc[j] * iptr[j];
+      accum[1] += sinc[j + 1] * iptr[j + 1];
+      accum[2] += sinc[j + 2] * iptr[j + 2];
+      accum[3] += sinc[j + 3] * iptr[j + 3];
     }
+    sum = accum[0] + accum[1] + accum[2] + accum[3];
+#else
+    sum = inner_product_single (sinc, iptr, N);
+#endif
 
-    *out = PSHR32 (sum, 15);
-    out += st->out_stride;
-    out_sample++;
-    last_sample += st->int_advance;
-    samp_frac_num += st->frac_advance;
-    if (samp_frac_num >= st->den_rate) {
-      samp_frac_num -= st->den_rate;
+    out[out_stride * out_sample++] = PSHR32 (sum, 15);
+    last_sample += int_advance;
+    samp_frac_num += frac_advance;
+    if (samp_frac_num >= den_rate) {
+      samp_frac_num -= den_rate;
       last_sample++;
     }
   }
+
   st->last_sample[channel_index] = last_sample;
   st->samp_frac_num[channel_index] = samp_frac_num;
   return out_sample;
@@ -428,49 +434,46 @@ resampler_basic_direct_double (SpeexResamplerState * st,
     spx_uint32_t channel_index, const spx_word16_t * in, spx_uint32_t * in_len,
     spx_word16_t * out, spx_uint32_t * out_len)
 {
-  int N = st->filt_len;
+  const int N = st->filt_len;
   int out_sample = 0;
-  spx_word16_t *mem;
   int last_sample = st->last_sample[channel_index];
   spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index];
+  const spx_word16_t *sinc_table = st->sinc_table;
+  const int out_stride = st->out_stride;
+  const int int_advance = st->int_advance;
+  const int frac_advance = st->frac_advance;
+  const spx_uint32_t den_rate = st->den_rate;
+  double sum;
+  int j;
 
-  mem = st->mem + channel_index * st->mem_alloc_size;
   while (!(last_sample >= (spx_int32_t) * in_len
           || out_sample >= (spx_int32_t) * out_len)) {
-    int j;
-    double sum = 0;
+    const spx_word16_t *sinc = &sinc_table[samp_frac_num * N];
+    const spx_word16_t *iptr = &in[last_sample];
 
-    /* We already have all the filter coefficients pre-computed in the table */
-    const spx_word16_t *ptr;
+#ifndef OVERRIDE_INNER_PRODUCT_DOUBLE
+    double accum[4] = { 0, 0, 0, 0 };
 
-    /* Do the memory part */
-    for (j = 0; last_sample - N + 1 + j < 0; j++) {
-      sum +=
-          MULT16_16 (mem[last_sample + j],
-          (double) st->sinc_table[samp_frac_num * st->filt_len + j]);
-    }
-
-    /* Do the new part */
-    if (in != NULL) {
-      ptr = in + st->in_stride * (last_sample - N + 1 + j);
-      for (; j < N; j++) {
-        sum +=
-            MULT16_16 (*ptr,
-            (double) st->sinc_table[samp_frac_num * st->filt_len + j]);
-        ptr += st->in_stride;
-      }
+    for (j = 0; j < N; j += 4) {
+      accum[0] += sinc[j] * iptr[j];
+      accum[1] += sinc[j + 1] * iptr[j + 1];
+      accum[2] += sinc[j + 2] * iptr[j + 2];
+      accum[3] += sinc[j + 3] * iptr[j + 3];
     }
+    sum = accum[0] + accum[1] + accum[2] + accum[3];
+#else
+    sum = inner_product_double (sinc, iptr, N);
+#endif
 
-    *out = sum;
-    out += st->out_stride;
-    out_sample++;
-    last_sample += st->int_advance;
-    samp_frac_num += st->frac_advance;
-    if (samp_frac_num >= st->den_rate) {
-      samp_frac_num -= st->den_rate;
+    out[out_stride * out_sample++] = PSHR32 (sum, 15);
+    last_sample += int_advance;
+    samp_frac_num += frac_advance;
+    if (samp_frac_num >= den_rate) {
+      samp_frac_num -= den_rate;
       last_sample++;
     }
   }
+
   st->last_sample[channel_index] = last_sample;
   st->samp_frac_num[channel_index] = samp_frac_num;
   return out_sample;
@@ -482,92 +485,75 @@ resampler_basic_interpolate_single (SpeexResamplerState * st,
     spx_uint32_t channel_index, const spx_word16_t * in, spx_uint32_t * in_len,
     spx_word16_t * out, spx_uint32_t * out_len)
 {
-  int N = st->filt_len;
+  const int N = st->filt_len;
   int out_sample = 0;
-  spx_word16_t *mem;
   int last_sample = st->last_sample[channel_index];
   spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index];
+  const int out_stride = st->out_stride;
+  const int int_advance = st->int_advance;
+  const int frac_advance = st->frac_advance;
+  const spx_uint32_t den_rate = st->den_rate;
+  int j;
+  spx_word32_t sum;
 
-  mem = st->mem + channel_index * st->mem_alloc_size;
   while (!(last_sample >= (spx_int32_t) * in_len
           || out_sample >= (spx_int32_t) * out_len)) {
-    int j;
-    spx_word32_t sum = 0;
+    const spx_word16_t *iptr = &in[last_sample];
 
-    /* We need to interpolate the sinc filter */
-    spx_word32_t accum[4] = { 0.f, 0.f, 0.f, 0.f };
-    spx_word16_t interp[4];
-    const spx_word16_t *ptr;
-    int offset;
-    spx_word16_t frac;
-
-    offset = samp_frac_num * st->oversample / st->den_rate;
+    const int offset = samp_frac_num * st->oversample / st->den_rate;
 #ifdef FIXED_POINT
-    frac =
+    const spx_word16_t frac =
         PDIV32 (SHL32 ((samp_frac_num * st->oversample) % st->den_rate, 15),
         st->den_rate);
 #else
-    frac =
+    const spx_word16_t frac =
         ((float) ((samp_frac_num * st->oversample) % st->den_rate)) /
         st->den_rate;
 #endif
-    /* This code is written like this to make it easy to optimise with SIMD.
-       For most DSPs, it would be best to split the loops in two because most DSPs 
-       have only two accumulators */
-    for (j = 0; last_sample - N + 1 + j < 0; j++) {
-      spx_word16_t curr_mem = mem[last_sample + j];
+    spx_word16_t interp[4];
 
+
+#ifndef OVERRIDE_INTERPOLATE_PRODUCT_SINGLE
+    spx_word32_t accum[4] = { 0, 0, 0, 0 };
+
+    for (j = 0; j < N; j++) {
+      const spx_word16_t curr_in = iptr[j];
       accum[0] +=
-          MULT16_16 (curr_mem,
+          MULT16_16 (curr_in,
           st->sinc_table[4 + (j + 1) * st->oversample - offset - 2]);
       accum[1] +=
-          MULT16_16 (curr_mem,
+          MULT16_16 (curr_in,
           st->sinc_table[4 + (j + 1) * st->oversample - offset - 1]);
       accum[2] +=
-          MULT16_16 (curr_mem,
+          MULT16_16 (curr_in,
           st->sinc_table[4 + (j + 1) * st->oversample - offset]);
       accum[3] +=
-          MULT16_16 (curr_mem,
+          MULT16_16 (curr_in,
           st->sinc_table[4 + (j + 1) * st->oversample - offset + 1]);
     }
 
-    if (in != NULL) {
-      ptr = in + st->in_stride * (last_sample - N + 1 + j);
-      /* Do the new part */
-      for (; j < N; j++) {
-        spx_word16_t curr_in = *ptr;
-
-        ptr += st->in_stride;
-        accum[0] +=
-            MULT16_16 (curr_in,
-            st->sinc_table[4 + (j + 1) * st->oversample - offset - 2]);
-        accum[1] +=
-            MULT16_16 (curr_in,
-            st->sinc_table[4 + (j + 1) * st->oversample - offset - 1]);
-        accum[2] +=
-            MULT16_16 (curr_in,
-            st->sinc_table[4 + (j + 1) * st->oversample - offset]);
-        accum[3] +=
-            MULT16_16 (curr_in,
-            st->sinc_table[4 + (j + 1) * st->oversample - offset + 1]);
-      }
-    }
     cubic_coef (frac, interp);
     sum =
         MULT16_32_Q15 (interp[0], accum[0]) + MULT16_32_Q15 (interp[1],
         accum[1]) + MULT16_32_Q15 (interp[2],
         accum[2]) + MULT16_32_Q15 (interp[3], accum[3]);
+#else
+    cubic_coef (frac, interp);
+    sum =
+        interpolate_product_single (iptr,
+        st->sinc_table + st->oversample + 4 - offset - 2, N, st->oversample,
+        interp);
+#endif
 
-    *out = PSHR32 (sum, 15);
-    out += st->out_stride;
-    out_sample++;
-    last_sample += st->int_advance;
-    samp_frac_num += st->frac_advance;
-    if (samp_frac_num >= st->den_rate) {
-      samp_frac_num -= st->den_rate;
+    out[out_stride * out_sample++] = PSHR32 (sum, 15);
+    last_sample += int_advance;
+    samp_frac_num += frac_advance;
+    if (samp_frac_num >= den_rate) {
+      samp_frac_num -= den_rate;
       last_sample++;
     }
   }
+
   st->last_sample[channel_index] = last_sample;
   st->samp_frac_num[channel_index] = samp_frac_num;
   return out_sample;
@@ -581,81 +567,75 @@ resampler_basic_interpolate_double (SpeexResamplerState * st,
     spx_uint32_t channel_index, const spx_word16_t * in, spx_uint32_t * in_len,
     spx_word16_t * out, spx_uint32_t * out_len)
 {
-  int N = st->filt_len;
+  const int N = st->filt_len;
   int out_sample = 0;
-  spx_word16_t *mem;
   int last_sample = st->last_sample[channel_index];
   spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index];
+  const int out_stride = st->out_stride;
+  const int int_advance = st->int_advance;
+  const int frac_advance = st->frac_advance;
+  const spx_uint32_t den_rate = st->den_rate;
+  int j;
+  spx_word32_t sum;
 
-  mem = st->mem + channel_index * st->mem_alloc_size;
   while (!(last_sample >= (spx_int32_t) * in_len
           || out_sample >= (spx_int32_t) * out_len)) {
-    int j;
-    spx_word32_t sum = 0;
-
-    /* We need to interpolate the sinc filter */
-    double accum[4] = { 0.f, 0.f, 0.f, 0.f };
-    float interp[4];
-    const spx_word16_t *ptr;
-    float alpha = ((float) samp_frac_num) / st->den_rate;
-    int offset = samp_frac_num * st->oversample / st->den_rate;
-    float frac = alpha * st->oversample - offset;
-
-    /* This code is written like this to make it easy to optimise with SIMD.
-       For most DSPs, it would be best to split the loops in two because most DSPs 
-       have only two accumulators */
-    for (j = 0; last_sample - N + 1 + j < 0; j++) {
-      double curr_mem = mem[last_sample + j];
+    const spx_word16_t *iptr = &in[last_sample];
 
+    const int offset = samp_frac_num * st->oversample / st->den_rate;
+#ifdef FIXED_POINT
+    const spx_word16_t frac =
+        PDIV32 (SHL32 ((samp_frac_num * st->oversample) % st->den_rate, 15),
+        st->den_rate);
+#else
+    const spx_word16_t frac =
+        ((float) ((samp_frac_num * st->oversample) % st->den_rate)) /
+        st->den_rate;
+#endif
+    spx_word16_t interp[4];
+
+
+#ifndef OVERRIDE_INTERPOLATE_PRODUCT_DOUBLE
+    double accum[4] = { 0, 0, 0, 0 };
+
+    for (j = 0; j < N; j++) {
+      const double curr_in = iptr[j];
       accum[0] +=
-          MULT16_16 (curr_mem,
+          MULT16_16 (curr_in,
           st->sinc_table[4 + (j + 1) * st->oversample - offset - 2]);
       accum[1] +=
-          MULT16_16 (curr_mem,
+          MULT16_16 (curr_in,
           st->sinc_table[4 + (j + 1) * st->oversample - offset - 1]);
       accum[2] +=
-          MULT16_16 (curr_mem,
+          MULT16_16 (curr_in,
           st->sinc_table[4 + (j + 1) * st->oversample - offset]);
       accum[3] +=
-          MULT16_16 (curr_mem,
+          MULT16_16 (curr_in,
           st->sinc_table[4 + (j + 1) * st->oversample - offset + 1]);
     }
-    if (in != NULL) {
-      ptr = in + st->in_stride * (last_sample - N + 1 + j);
-      /* Do the new part */
-      for (; j < N; j++) {
-        double curr_in = *ptr;
-
-        ptr += st->in_stride;
-        accum[0] +=
-            MULT16_16 (curr_in,
-            st->sinc_table[4 + (j + 1) * st->oversample - offset - 2]);
-        accum[1] +=
-            MULT16_16 (curr_in,
-            st->sinc_table[4 + (j + 1) * st->oversample - offset - 1]);
-        accum[2] +=
-            MULT16_16 (curr_in,
-            st->sinc_table[4 + (j + 1) * st->oversample - offset]);
-        accum[3] +=
-            MULT16_16 (curr_in,
-            st->sinc_table[4 + (j + 1) * st->oversample - offset + 1]);
-      }
-    }
+
+    cubic_coef (frac, interp);
+    sum =
+        MULT16_32_Q15 (interp[0], accum[0]) + MULT16_32_Q15 (interp[1],
+        accum[1]) + MULT16_32_Q15 (interp[2],
+        accum[2]) + MULT16_32_Q15 (interp[3], accum[3]);
+#else
     cubic_coef (frac, interp);
     sum =
-        interp[0] * accum[0] + interp[1] * accum[1] + interp[2] * accum[2] +
-        interp[3] * accum[3];
-
-    *out = PSHR32 (sum, 15);
-    out += st->out_stride;
-    out_sample++;
-    last_sample += st->int_advance;
-    samp_frac_num += st->frac_advance;
-    if (samp_frac_num >= st->den_rate) {
-      samp_frac_num -= st->den_rate;
+        interpolate_product_double (iptr,
+        st->sinc_table + st->oversample + 4 - offset - 2, N, st->oversample,
+        interp);
+#endif
+
+    out[out_stride * out_sample++] = PSHR32 (sum, 15);
+    last_sample += int_advance;
+    samp_frac_num += frac_advance;
+    if (samp_frac_num >= den_rate) {
+      samp_frac_num -= den_rate;
       last_sample++;
     }
   }
+
   st->last_sample[channel_index] = last_sample;
   st->samp_frac_num[channel_index] = samp_frac_num;
   return out_sample;
@@ -698,7 +678,6 @@ update_filter (SpeexResamplerState * st)
   /* Choose the resampling type that requires the least amount of memory */
   if (st->den_rate <= st->oversample) {
     spx_uint32_t i;
-
     if (!st->sinc_table)
       st->sinc_table =
           (spx_word16_t *) speex_alloc (st->filt_len * st->den_rate *
@@ -711,7 +690,6 @@ update_filter (SpeexResamplerState * st)
     }
     for (i = 0; i < st->den_rate; i++) {
       spx_int32_t j;
-
       for (j = 0; j < st->filt_len; j++) {
         st->sinc_table[i * st->filt_len + j] =
             sinc (st->cutoff,
@@ -731,7 +709,6 @@ update_filter (SpeexResamplerState * st)
     /*fprintf (stderr, "resampler uses direct sinc table and normalised cutoff %f\n", cutoff); */
   } else {
     spx_int32_t i;
-
     if (!st->sinc_table)
       st->sinc_table =
           (spx_word16_t *) speex_alloc ((st->filt_len * st->oversample +
@@ -765,41 +742,36 @@ update_filter (SpeexResamplerState * st)
      due to handling of lots of corner cases. */
   if (!st->mem) {
     spx_uint32_t i;
-
+    st->mem_alloc_size = st->filt_len - 1 + st->buffer_size;
     st->mem =
-        (spx_word16_t *) speex_alloc (st->nb_channels * (st->filt_len -
-            1) * sizeof (spx_word16_t));
-    for (i = 0; i < st->nb_channels * (st->filt_len - 1); i++)
+        (spx_word16_t *) speex_alloc (st->nb_channels * st->mem_alloc_size *
+        sizeof (spx_word16_t));
+    for (i = 0; i < st->nb_channels * st->mem_alloc_size; i++)
       st->mem[i] = 0;
-    st->mem_alloc_size = st->filt_len - 1;
     /*speex_warning("init filter"); */
   } else if (!st->started) {
     spx_uint32_t i;
-
+    st->mem_alloc_size = st->filt_len - 1 + st->buffer_size;
     st->mem =
         (spx_word16_t *) speex_realloc (st->mem,
-        st->nb_channels * (st->filt_len - 1) * sizeof (spx_word16_t));
-    for (i = 0; i < st->nb_channels * (st->filt_len - 1); i++)
+        st->nb_channels * st->mem_alloc_size * sizeof (spx_word16_t));
+    for (i = 0; i < st->nb_channels * st->mem_alloc_size; i++)
       st->mem[i] = 0;
-    st->mem_alloc_size = st->filt_len - 1;
     /*speex_warning("reinit filter"); */
   } else if (st->filt_len > old_length) {
     spx_int32_t i;
-
     /* Increase the filter length */
     /*speex_warning("increase filter size"); */
     int old_alloc_size = st->mem_alloc_size;
-
-    if (st->filt_len - 1 > st->mem_alloc_size) {
+    if ((st->filt_len - 1 + st->buffer_size) > st->mem_alloc_size) {
+      st->mem_alloc_size = st->filt_len - 1 + st->buffer_size;
       st->mem =
           (spx_word16_t *) speex_realloc (st->mem,
-          st->nb_channels * (st->filt_len - 1) * sizeof (spx_word16_t));
-      st->mem_alloc_size = st->filt_len - 1;
+          st->nb_channels * st->mem_alloc_size * sizeof (spx_word16_t));
     }
     for (i = st->nb_channels - 1; i >= 0; i--) {
       spx_int32_t j;
       spx_uint32_t olen = old_length;
-
       /*if (st->magic_samples[i]) */
       {
         /* Try and remove the magic samples as if nothing had happened */
@@ -834,13 +806,11 @@ update_filter (SpeexResamplerState * st)
     }
   } else if (st->filt_len < old_length) {
     spx_uint32_t i;
-
     /* Reduce filter length, this a bit tricky. We need to store some of the memory as "magic"
        samples so they can be used directly as input the next time(s) */
     for (i = 0; i < st->nb_channels; i++) {
       spx_uint32_t j;
       spx_uint32_t old_magic = st->magic_samples[i];
-
       st->magic_samples[i] = (old_length - st->filt_len) / 2;
       /* We must copy some of the memory that's no longer used */
       /* Copy data going backward */
@@ -853,7 +823,7 @@ update_filter (SpeexResamplerState * st)
 
 }
 
-SpeexResamplerState *
+EXPORT SpeexResamplerState *
 speex_resampler_init (spx_uint32_t nb_channels, spx_uint32_t in_rate,
     spx_uint32_t out_rate, int quality, int *err)
 {
@@ -861,14 +831,13 @@ speex_resampler_init (spx_uint32_t nb_channels, spx_uint32_t in_rate,
       out_rate, quality, err);
 }
 
-SpeexResamplerState *
+EXPORT SpeexResamplerState *
 speex_resampler_init_frac (spx_uint32_t nb_channels, spx_uint32_t ratio_num,
     spx_uint32_t ratio_den, spx_uint32_t in_rate, spx_uint32_t out_rate,
     int quality, int *err)
 {
   spx_uint32_t i;
   SpeexResamplerState *st;
-
   if (quality > 10 || quality < 0) {
     if (err)
       *err = RESAMPLER_ERR_INVALID_ARG;
@@ -893,6 +862,12 @@ speex_resampler_init_frac (spx_uint32_t nb_channels, spx_uint32_t ratio_num,
   st->in_stride = 1;
   st->out_stride = 1;
 
+#ifdef FIXED_POINT
+  st->buffer_size = 160;
+#else
+  st->buffer_size = 160;
+#endif
+
   /* Per channel data */
   st->last_sample = (spx_int32_t *) speex_alloc (nb_channels * sizeof (int));
   st->magic_samples = (spx_uint32_t *) speex_alloc (nb_channels * sizeof (int));
@@ -916,7 +891,7 @@ speex_resampler_init_frac (spx_uint32_t nb_channels, spx_uint32_t ratio_num,
   return st;
 }
 
-void
+EXPORT void
 speex_resampler_destroy (SpeexResamplerState * st)
 {
   speex_free (st->mem);
@@ -927,249 +902,193 @@ speex_resampler_destroy (SpeexResamplerState * st)
   speex_free (st);
 }
 
-
-
 static int
 speex_resampler_process_native (SpeexResamplerState * st,
-    spx_uint32_t channel_index, const spx_word16_t * in, spx_uint32_t * in_len,
-    spx_word16_t * out, spx_uint32_t * out_len)
+    spx_uint32_t channel_index, spx_uint32_t * in_len, spx_word16_t * out,
+    spx_uint32_t * out_len)
 {
   int j = 0;
-  int N = st->filt_len;
+  const int N = st->filt_len;
   int out_sample = 0;
-  spx_word16_t *mem;
-  spx_uint32_t tmp_out_len = 0;
+  spx_word16_t *mem = st->mem + channel_index * st->mem_alloc_size;
+  spx_uint32_t ilen;
 
-  mem = st->mem + channel_index * st->mem_alloc_size;
   st->started = 1;
 
-  /* Handle the case where we have samples left from a reduction in filter length */
-  if (st->magic_samples[channel_index]) {
-    int istride_save;
-    spx_uint32_t tmp_in_len;
-    spx_uint32_t tmp_magic;
-
-    istride_save = st->in_stride;
-    tmp_in_len = st->magic_samples[channel_index];
-    tmp_out_len = *out_len;
-    /* magic_samples needs to be set to zero to avoid infinite recursion */
-    tmp_magic = st->magic_samples[channel_index];
-    st->magic_samples[channel_index] = 0;
-    st->in_stride = 1;
-    speex_resampler_process_native (st, channel_index, mem + N - 1, &tmp_in_len,
-        out, &tmp_out_len);
-    st->in_stride = istride_save;
-    /*speex_warning_int("extra samples:", tmp_out_len); */
-    /* If we couldn't process all "magic" input samples, save the rest for next time */
-    if (tmp_in_len < tmp_magic) {
-      spx_uint32_t i;
-
-      st->magic_samples[channel_index] = tmp_magic - tmp_in_len;
-      for (i = 0; i < st->magic_samples[channel_index]; i++)
-        mem[N - 1 + i] = mem[N - 1 + i + tmp_in_len];
-    }
-    out += tmp_out_len * st->out_stride;
-    *out_len -= tmp_out_len;
-  }
-
   /* Call the right resampler through the function ptr */
-  out_sample = st->resampler_ptr (st, channel_index, in, in_len, out, out_len);
+  out_sample = st->resampler_ptr (st, channel_index, mem, in_len, out, out_len);
 
   if (st->last_sample[channel_index] < (spx_int32_t) * in_len)
     *in_len = st->last_sample[channel_index];
-  *out_len = out_sample + tmp_out_len;
+  *out_len = out_sample;
   st->last_sample[channel_index] -= *in_len;
 
-  for (j = 0; j < N - 1 - (spx_int32_t) * in_len; j++)
-    mem[j] = mem[j + *in_len];
-  if (in != NULL) {
-    for (; j < N - 1; j++)
-      mem[j] = in[st->in_stride * (j + *in_len - N + 1)];
-  } else {
-    for (; j < N - 1; j++)
-      mem[j] = 0;
-  }
+  ilen = *in_len;
+
+  for (j = 0; j < N - 1; ++j)
+    mem[j] = mem[j + ilen];
+
   return RESAMPLER_ERR_SUCCESS;
 }
 
-#define FIXED_STACK_ALLOC 1024
-
-#ifdef FIXED_POINT
-int
-speex_resampler_process_float (SpeexResamplerState * st,
-    spx_uint32_t channel_index, const float *in, spx_uint32_t * in_len,
-    float *out, spx_uint32_t * out_len)
+static int
+speex_resampler_magic (SpeexResamplerState * st, spx_uint32_t channel_index,
+    spx_word16_t ** out, spx_uint32_t out_len)
 {
-  spx_uint32_t i;
-  int istride_save, ostride_save;
+  spx_uint32_t tmp_in_len = st->magic_samples[channel_index];
+  spx_word16_t *mem = st->mem + channel_index * st->mem_alloc_size;
+  const int N = st->filt_len;
 
-#ifdef VAR_ARRAYS
-  spx_word16_t x[*in_len];
-  spx_word16_t y[*out_len];
+  speex_resampler_process_native (st, channel_index, &tmp_in_len, *out,
+      &out_len);
 
-  /*VARDECL(spx_word16_t *x);
-     VARDECL(spx_word16_t *y);
-     ALLOC(x, *in_len, spx_word16_t);
-     ALLOC(y, *out_len, spx_word16_t); */
-  istride_save = st->in_stride;
-  ostride_save = st->out_stride;
-  if (in != NULL) {
-    for (i = 0; i < *in_len; i++)
-      x[i] = WORD2INT (in[i * st->in_stride]);
-    st->in_stride = st->out_stride = 1;
-    speex_resampler_process_native (st, channel_index, x, in_len, y, out_len);
-  } else {
-    st->in_stride = st->out_stride = 1;
-    speex_resampler_process_native (st, channel_index, NULL, in_len, y,
-        out_len);
-  }
-  st->in_stride = istride_save;
-  st->out_stride = ostride_save;
-  for (i = 0; i < *out_len; i++)
-    out[i * st->out_stride] = y[i];
-#else
-  spx_word16_t x[FIXED_STACK_ALLOC];
-  spx_word16_t y[FIXED_STACK_ALLOC];
-  spx_uint32_t ilen = *in_len, olen = *out_len;
+  st->magic_samples[channel_index] -= tmp_in_len;
 
-  istride_save = st->in_stride;
-  ostride_save = st->out_stride;
-  while (ilen && olen) {
-    spx_uint32_t ichunk, ochunk;
-
-    ichunk = ilen;
-    ochunk = olen;
-    if (ichunk > FIXED_STACK_ALLOC)
-      ichunk = FIXED_STACK_ALLOC;
-    if (ochunk > FIXED_STACK_ALLOC)
-      ochunk = FIXED_STACK_ALLOC;
-    if (in != NULL) {
-      for (i = 0; i < ichunk; i++)
-        x[i] = WORD2INT (in[i * st->in_stride]);
-      st->in_stride = st->out_stride = 1;
-      speex_resampler_process_native (st, channel_index, x, &ichunk, y,
-          &ochunk);
-    } else {
-      st->in_stride = st->out_stride = 1;
-      speex_resampler_process_native (st, channel_index, NULL, &ichunk, y,
-          &ochunk);
-    }
-    st->in_stride = istride_save;
-    st->out_stride = ostride_save;
-    for (i = 0; i < ochunk; i++)
-      out[i * st->out_stride] = y[i];
-    out += ochunk;
-    in += ichunk;
-    ilen -= ichunk;
-    olen -= ochunk;
+  /* If we couldn't process all "magic" input samples, save the rest for next time */
+  if (st->magic_samples[channel_index]) {
+    spx_uint32_t i;
+    for (i = 0; i < st->magic_samples[channel_index]; i++)
+      mem[N - 1 + i] = mem[N - 1 + i + tmp_in_len];
   }
-  *in_len -= ilen;
-  *out_len -= olen;
-#endif
-  return RESAMPLER_ERR_SUCCESS;
+  *out += out_len * st->out_stride;
+  return out_len;
 }
 
-int
+#ifdef FIXED_POINT
+EXPORT int
 speex_resampler_process_int (SpeexResamplerState * st,
     spx_uint32_t channel_index, const spx_int16_t * in, spx_uint32_t * in_len,
     spx_int16_t * out, spx_uint32_t * out_len)
-{
-  return speex_resampler_process_native (st, channel_index, in, in_len, out,
-      out_len);
-}
 #else
-int
+EXPORT int
 speex_resampler_process_float (SpeexResamplerState * st,
     spx_uint32_t channel_index, const float *in, spx_uint32_t * in_len,
     float *out, spx_uint32_t * out_len)
+#endif
 {
-  return speex_resampler_process_native (st, channel_index, in, in_len, out,
-      out_len);
+  int j;
+  spx_uint32_t ilen = *in_len;
+  spx_uint32_t olen = *out_len;
+  spx_word16_t *x = st->mem + channel_index * st->mem_alloc_size;
+  const int filt_offs = st->filt_len - 1;
+  const spx_uint32_t xlen = st->mem_alloc_size - filt_offs;
+  const int istride = st->in_stride;
+
+  if (st->magic_samples[channel_index])
+    olen -= speex_resampler_magic (st, channel_index, &out, olen);
+  if (!st->magic_samples[channel_index]) {
+    while (ilen && olen) {
+      spx_uint32_t ichunk = (ilen > xlen) ? xlen : ilen;
+      spx_uint32_t ochunk = olen;
+
+      if (in) {
+        for (j = 0; j < ichunk; ++j)
+          x[j + filt_offs] = in[j * istride];
+      } else {
+        for (j = 0; j < ichunk; ++j)
+          x[j + filt_offs] = 0;
+      }
+      speex_resampler_process_native (st, channel_index, &ichunk, out, &ochunk);
+      ilen -= ichunk;
+      olen -= ochunk;
+      out += ochunk * st->out_stride;
+      if (in)
+        in += ichunk * istride;
+    }
+  }
+  *in_len -= ilen;
+  *out_len -= olen;
+  return RESAMPLER_ERR_SUCCESS;
 }
 
-int
+#ifdef FIXED_POINT
+EXPORT int
+speex_resampler_process_float (SpeexResamplerState * st,
+    spx_uint32_t channel_index, const float *in, spx_uint32_t * in_len,
+    float *out, spx_uint32_t * out_len)
+#else
+EXPORT int
 speex_resampler_process_int (SpeexResamplerState * st,
     spx_uint32_t channel_index, const spx_int16_t * in, spx_uint32_t * in_len,
     spx_int16_t * out, spx_uint32_t * out_len)
+#endif
 {
-  spx_uint32_t i;
-  int istride_save, ostride_save;
-
+  int j;
+  const int istride_save = st->in_stride;
+  const int ostride_save = st->out_stride;
+  spx_uint32_t ilen = *in_len;
+  spx_uint32_t olen = *out_len;
+  spx_word16_t *x = st->mem + channel_index * st->mem_alloc_size;
+  const spx_uint32_t xlen = st->mem_alloc_size - (st->filt_len - 1);
 #ifdef VAR_ARRAYS
-  spx_word16_t x[*in_len];
-  spx_word16_t y[*out_len];
-
-  /*VARDECL(spx_word16_t *x);
-     VARDECL(spx_word16_t *y);
-     ALLOC(x, *in_len, spx_word16_t);
-     ALLOC(y, *out_len, spx_word16_t); */
-  istride_save = st->in_stride;
-  ostride_save = st->out_stride;
-  if (in != NULL) {
-    for (i = 0; i < *in_len; i++)
-      x[i] = in[i * st->in_stride];
-    st->in_stride = st->out_stride = 1;
-    speex_resampler_process_native (st, channel_index, x, in_len, y, out_len);
-  } else {
-    st->in_stride = st->out_stride = 1;
-    speex_resampler_process_native (st, channel_index, NULL, in_len, y,
-        out_len);
-  }
-  st->in_stride = istride_save;
-  st->out_stride = ostride_save;
-  for (i = 0; i < *out_len; i++)
-    out[i * st->out_stride] = WORD2INT (y[i]);
+  const unsigned int ylen =
+      (olen < FIXED_STACK_ALLOC) ? olen : FIXED_STACK_ALLOC;
+  VARDECL (spx_word16_t * ystack);
+  ALLOC (ystack, ylen, spx_word16_t);
 #else
-  spx_word16_t x[FIXED_STACK_ALLOC];
-  spx_word16_t y[FIXED_STACK_ALLOC];
-  spx_uint32_t ilen = *in_len, olen = *out_len;
+  const unsigned int ylen = FIXED_STACK_ALLOC;
+  spx_word16_t ystack[FIXED_STACK_ALLOC];
+#endif
+
+  st->out_stride = 1;
 
-  istride_save = st->in_stride;
-  ostride_save = st->out_stride;
   while (ilen && olen) {
-    spx_uint32_t ichunk, ochunk;
-
-    ichunk = ilen;
-    ochunk = olen;
-    if (ichunk > FIXED_STACK_ALLOC)
-      ichunk = FIXED_STACK_ALLOC;
-    if (ochunk > FIXED_STACK_ALLOC)
-      ochunk = FIXED_STACK_ALLOC;
-    if (in != NULL) {
-      for (i = 0; i < ichunk; i++)
-        x[i] = in[i * st->in_stride];
-      st->in_stride = st->out_stride = 1;
-      speex_resampler_process_native (st, channel_index, x, &ichunk, y,
-          &ochunk);
+    spx_word16_t *y = ystack;
+    spx_uint32_t ichunk = (ilen > xlen) ? xlen : ilen;
+    spx_uint32_t ochunk = (olen > ylen) ? ylen : olen;
+    spx_uint32_t omagic = 0;
+
+    if (st->magic_samples[channel_index]) {
+      omagic = speex_resampler_magic (st, channel_index, &y, ochunk);
+      ochunk -= omagic;
+      olen -= omagic;
+    }
+    if (!st->magic_samples[channel_index]) {
+      if (in) {
+        for (j = 0; j < ichunk; ++j)
+#ifdef FIXED_POINT
+          x[j + st->filt_len - 1] = WORD2INT (in[j * istride_save]);
+#else
+          x[j + st->filt_len - 1] = in[j * istride_save];
+#endif
+      } else {
+        for (j = 0; j < ichunk; ++j)
+          x[j + st->filt_len - 1] = 0;
+      }
+
+      speex_resampler_process_native (st, channel_index, &ichunk, y, &ochunk);
     } else {
-      st->in_stride = st->out_stride = 1;
-      speex_resampler_process_native (st, channel_index, NULL, &ichunk, y,
-          &ochunk);
+      ichunk = 0;
+      ochunk = 0;
     }
-    st->in_stride = istride_save;
-    st->out_stride = ostride_save;
-    for (i = 0; i < ochunk; i++)
-      out[i * st->out_stride] = WORD2INT (y[i]);
-    out += ochunk;
-    in += ichunk;
+
+    for (j = 0; j < ochunk + omagic; ++j)
+#ifdef FIXED_POINT
+      out[j * ostride_save] = ystack[j];
+#else
+      out[j * ostride_save] = WORD2INT (ystack[j]);
+#endif
+
     ilen -= ichunk;
     olen -= ochunk;
+    out += (ochunk + omagic) * ostride_save;
+    if (in)
+      in += ichunk * istride_save;
   }
+  st->out_stride = ostride_save;
   *in_len -= ilen;
   *out_len -= olen;
-#endif
+
   return RESAMPLER_ERR_SUCCESS;
 }
-#endif
 
-int
+EXPORT int
 speex_resampler_process_interleaved_float (SpeexResamplerState * st,
     const float *in, spx_uint32_t * in_len, float *out, spx_uint32_t * out_len)
 {
   spx_uint32_t i;
   int istride_save, ostride_save;
   spx_uint32_t bak_len = *out_len;
-
   istride_save = st->in_stride;
   ostride_save = st->out_stride;
   st->in_stride = st->out_stride = st->nb_channels;
@@ -1185,8 +1104,7 @@ speex_resampler_process_interleaved_float (SpeexResamplerState * st,
   return RESAMPLER_ERR_SUCCESS;
 }
 
-
-int
+EXPORT int
 speex_resampler_process_interleaved_int (SpeexResamplerState * st,
     const spx_int16_t * in, spx_uint32_t * in_len, spx_int16_t * out,
     spx_uint32_t * out_len)
@@ -1194,7 +1112,6 @@ speex_resampler_process_interleaved_int (SpeexResamplerState * st,
   spx_uint32_t i;
   int istride_save, ostride_save;
   spx_uint32_t bak_len = *out_len;
-
   istride_save = st->in_stride;
   ostride_save = st->out_stride;
   st->in_stride = st->out_stride = st->nb_channels;
@@ -1210,7 +1127,7 @@ speex_resampler_process_interleaved_int (SpeexResamplerState * st,
   return RESAMPLER_ERR_SUCCESS;
 }
 
-int
+EXPORT int
 speex_resampler_set_rate (SpeexResamplerState * st, spx_uint32_t in_rate,
     spx_uint32_t out_rate)
 {
@@ -1218,7 +1135,7 @@ speex_resampler_set_rate (SpeexResamplerState * st, spx_uint32_t in_rate,
       out_rate);
 }
 
-void
+EXPORT void
 speex_resampler_get_rate (SpeexResamplerState * st, spx_uint32_t * in_rate,
     spx_uint32_t * out_rate)
 {
@@ -1226,14 +1143,13 @@ speex_resampler_get_rate (SpeexResamplerState * st, spx_uint32_t * in_rate,
   *out_rate = st->out_rate;
 }
 
-int
+EXPORT int
 speex_resampler_set_rate_frac (SpeexResamplerState * st, spx_uint32_t ratio_num,
     spx_uint32_t ratio_den, spx_uint32_t in_rate, spx_uint32_t out_rate)
 {
   spx_uint32_t fact;
   spx_uint32_t old_den;
   spx_uint32_t i;
-
   if (st->in_rate == in_rate && st->out_rate == out_rate
       && st->num_rate == ratio_num && st->den_rate == ratio_den)
     return RESAMPLER_ERR_SUCCESS;
@@ -1265,7 +1181,7 @@ speex_resampler_set_rate_frac (SpeexResamplerState * st, spx_uint32_t ratio_num,
   return RESAMPLER_ERR_SUCCESS;
 }
 
-void
+EXPORT void
 speex_resampler_get_ratio (SpeexResamplerState * st, spx_uint32_t * ratio_num,
     spx_uint32_t * ratio_den)
 {
@@ -1273,7 +1189,7 @@ speex_resampler_get_ratio (SpeexResamplerState * st, spx_uint32_t * ratio_num,
   *ratio_den = st->den_rate;
 }
 
-int
+EXPORT int
 speex_resampler_set_quality (SpeexResamplerState * st, int quality)
 {
   if (quality > 10 || quality < 0)
@@ -1286,73 +1202,71 @@ speex_resampler_set_quality (SpeexResamplerState * st, int quality)
   return RESAMPLER_ERR_SUCCESS;
 }
 
-void
+EXPORT void
 speex_resampler_get_quality (SpeexResamplerState * st, int *quality)
 {
   *quality = st->quality;
 }
 
-void
+EXPORT void
 speex_resampler_set_input_stride (SpeexResamplerState * st, spx_uint32_t stride)
 {
   st->in_stride = stride;
 }
 
-void
+EXPORT void
 speex_resampler_get_input_stride (SpeexResamplerState * st,
     spx_uint32_t * stride)
 {
   *stride = st->in_stride;
 }
 
-void
+EXPORT void
 speex_resampler_set_output_stride (SpeexResamplerState * st,
     spx_uint32_t stride)
 {
   st->out_stride = stride;
 }
 
-void
+EXPORT void
 speex_resampler_get_output_stride (SpeexResamplerState * st,
     spx_uint32_t * stride)
 {
   *stride = st->out_stride;
 }
 
-int
+EXPORT int
 speex_resampler_get_input_latency (SpeexResamplerState * st)
 {
   return st->filt_len / 2;
 }
 
-int
+EXPORT int
 speex_resampler_get_output_latency (SpeexResamplerState * st)
 {
   return ((st->filt_len / 2) * st->den_rate +
       (st->num_rate >> 1)) / st->num_rate;
 }
 
-int
+EXPORT int
 speex_resampler_skip_zeros (SpeexResamplerState * st)
 {
   spx_uint32_t i;
-
   for (i = 0; i < st->nb_channels; i++)
     st->last_sample[i] = st->filt_len / 2;
   return RESAMPLER_ERR_SUCCESS;
 }
 
-int
+EXPORT int
 speex_resampler_reset_mem (SpeexResamplerState * st)
 {
   spx_uint32_t i;
-
   for (i = 0; i < st->nb_channels * (st->filt_len - 1); i++)
     st->mem[i] = 0;
   return RESAMPLER_ERR_SUCCESS;
 }
 
-const char *
+EXPORT const char *
 speex_resampler_strerror (int err)
 {
   switch (err) {
index ad832c5..a00c37c 100644 (file)
@@ -41,8 +41,6 @@
 
 #ifdef OUTSIDE_SPEEX
 
-#include <glib.h>
-
 /********* WARNING: MENTAL SANITY ENDS HERE *************/
 
 /* If the resampler is defined outside of Speex, we change the symbol names so that 
@@ -55,7 +53,7 @@
 
 #define CAT_PREFIX2(a,b) a ## b
 #define CAT_PREFIX(a,b) CAT_PREFIX2(a, b)
-      
+
 #define speex_resampler_init CAT_PREFIX(RANDOM_PREFIX,_resampler_init)
 #define speex_resampler_init_frac CAT_PREFIX(RANDOM_PREFIX,_resampler_init_frac)
 #define speex_resampler_destroy CAT_PREFIX(RANDOM_PREFIX,_resampler_destroy)
 #define spx_int32_t gint32
 #define spx_uint16_t guint16
 #define spx_uint32_t guint32
-      
+
 #else /* OUTSIDE_SPEEX */
 
-#include "speex/speex_types.h"
+#ifdef _BUILD_SPEEX
+# include "speex_types.h"
+#else
+# include <speex/speex_types.h>
+#endif
 
 #endif /* OUTSIDE_SPEEX */
 
 #ifdef __cplusplus
-extern "C" {
+extern "C"
+{
 #endif
 
 #define SPEEX_RESAMPLER_QUALITY_MAX 10
@@ -100,18 +103,19 @@ extern "C" {
 #define SPEEX_RESAMPLER_QUALITY_VOIP 3
 #define SPEEX_RESAMPLER_QUALITY_DESKTOP 5
 
-enum {
-   RESAMPLER_ERR_SUCCESS         = 0,
-   RESAMPLER_ERR_ALLOC_FAILED    = 1,
-   RESAMPLER_ERR_BAD_STATE       = 2,
-   RESAMPLER_ERR_INVALID_ARG     = 3,
-   RESAMPLER_ERR_PTR_OVERLAP     = 4,
-   
-   RESAMPLER_ERR_MAX_ERROR
-};
+  enum
+  {
+    RESAMPLER_ERR_SUCCESS = 0,
+    RESAMPLER_ERR_ALLOC_FAILED = 1,
+    RESAMPLER_ERR_BAD_STATE = 2,
+    RESAMPLER_ERR_INVALID_ARG = 3,
+    RESAMPLER_ERR_PTR_OVERLAP = 4,
+
+    RESAMPLER_ERR_MAX_ERROR
+  };
 
-struct SpeexResamplerState_;
-typedef struct SpeexResamplerState_ SpeexResamplerState;
+  struct SpeexResamplerState_;
+  typedef struct SpeexResamplerState_ SpeexResamplerState;
 
 /** Create a new resampler with integer input and output rates.
  * @param nb_channels Number of channels to be processed
@@ -122,11 +126,8 @@ typedef struct SpeexResamplerState_ SpeexResamplerState;
  * @return Newly created resampler state
  * @retval NULL Error: not enough memory
  */
-SpeexResamplerState *speex_resampler_init(spx_uint32_t nb_channels, 
-                                          spx_uint32_t in_rate, 
-                                          spx_uint32_t out_rate, 
-                                          int quality,
-                                          int *err);
+  SpeexResamplerState *speex_resampler_init (spx_uint32_t nb_channels,
+      spx_uint32_t in_rate, spx_uint32_t out_rate, int quality, int *err);
 
 /** Create a new resampler with fractional input/output rates. The sampling 
  * rate ratio is an arbitrary rational number with both the numerator and 
@@ -141,18 +142,15 @@ SpeexResamplerState *speex_resampler_init(spx_uint32_t nb_channels,
  * @return Newly created resampler state
  * @retval NULL Error: not enough memory
  */
-SpeexResamplerState *speex_resampler_init_frac(spx_uint32_t nb_channels, 
-                                               spx_uint32_t ratio_num, 
-                                               spx_uint32_t ratio_den, 
-                                               spx_uint32_t in_rate, 
-                                               spx_uint32_t out_rate, 
-                                               int quality,
-                                               int *err);
+  SpeexResamplerState *speex_resampler_init_frac (spx_uint32_t nb_channels,
+      spx_uint32_t ratio_num,
+      spx_uint32_t ratio_den,
+      spx_uint32_t in_rate, spx_uint32_t out_rate, int quality, int *err);
 
 /** Destroy a resampler state.
  * @param st Resampler state
  */
-void speex_resampler_destroy(SpeexResamplerState *st);
+  void speex_resampler_destroy (SpeexResamplerState * st);
 
 /** Resample a float array. The input and output buffers must *not* overlap.
  * @param st Resampler state
@@ -164,12 +162,10 @@ void speex_resampler_destroy(SpeexResamplerState *st);
  * @param out Output buffer
  * @param out_len Size of the output buffer. Returns the number of samples written
  */
-int speex_resampler_process_float(SpeexResamplerState *st, 
-                                   spx_uint32_t channel_index, 
-                                   const float *in, 
-                                   spx_uint32_t *in_len, 
-                                   float *out, 
-                                   spx_uint32_t *out_len);
+  int speex_resampler_process_float (SpeexResamplerState * st,
+      spx_uint32_t channel_index,
+      const float *in,
+      spx_uint32_t * in_len, float *out, spx_uint32_t * out_len);
 
 /** Resample an int array. The input and output buffers must *not* overlap.
  * @param st Resampler state
@@ -181,12 +177,10 @@ int speex_resampler_process_float(SpeexResamplerState *st,
  * @param out Output buffer
  * @param out_len Size of the output buffer. Returns the number of samples written
  */
-int speex_resampler_process_int(SpeexResamplerState *st, 
-                                 spx_uint32_t channel_index, 
-                                 const spx_int16_t *in, 
-                                 spx_uint32_t *in_len, 
-                                 spx_int16_t *out, 
-                                 spx_uint32_t *out_len);
+  int speex_resampler_process_int (SpeexResamplerState * st,
+      spx_uint32_t channel_index,
+      const spx_int16_t * in,
+      spx_uint32_t * in_len, spx_int16_t * out, spx_uint32_t * out_len);
 
 /** Resample an interleaved float array. The input and output buffers must *not* overlap.
  * @param st Resampler state
@@ -197,11 +191,9 @@ int speex_resampler_process_int(SpeexResamplerState *st,
  * @param out_len Size of the output buffer. Returns the number of samples written.
  * This is all per-channel.
  */
-int speex_resampler_process_interleaved_float(SpeexResamplerState *st, 
-                                               const float *in, 
-                                               spx_uint32_t *in_len, 
-                                               float *out, 
-                                               spx_uint32_t *out_len);
+  int speex_resampler_process_interleaved_float (SpeexResamplerState * st,
+      const float *in,
+      spx_uint32_t * in_len, float *out, spx_uint32_t * out_len);
 
 /** Resample an interleaved int array. The input and output buffers must *not* overlap.
  * @param st Resampler state
@@ -212,29 +204,25 @@ int speex_resampler_process_interleaved_float(SpeexResamplerState *st,
  * @param out_len Size of the output buffer. Returns the number of samples written.
  * This is all per-channel.
  */
-int speex_resampler_process_interleaved_int(SpeexResamplerState *st, 
-                                             const spx_int16_t *in, 
-                                             spx_uint32_t *in_len, 
-                                             spx_int16_t *out, 
-                                             spx_uint32_t *out_len);
+  int speex_resampler_process_interleaved_int (SpeexResamplerState * st,
+      const spx_int16_t * in,
+      spx_uint32_t * in_len, spx_int16_t * out, spx_uint32_t * out_len);
 
 /** Set (change) the input/output sampling rates (integer value).
  * @param st Resampler state
  * @param in_rate Input sampling rate (integer number of Hz).
  * @param out_rate Output sampling rate (integer number of Hz).
  */
-int speex_resampler_set_rate(SpeexResamplerState *st, 
-                              spx_uint32_t in_rate, 
-                              spx_uint32_t out_rate);
+  int speex_resampler_set_rate (SpeexResamplerState * st,
+      spx_uint32_t in_rate, spx_uint32_t out_rate);
 
 /** Get the current input/output sampling rates (integer value).
  * @param st Resampler state
  * @param in_rate Input sampling rate (integer number of Hz) copied.
  * @param out_rate Output sampling rate (integer number of Hz) copied.
  */
-void speex_resampler_get_rate(SpeexResamplerState *st, 
-                              spx_uint32_t *in_rate, 
-                              spx_uint32_t *out_rate);
+  void speex_resampler_get_rate (SpeexResamplerState * st,
+      spx_uint32_t * in_rate, spx_uint32_t * out_rate);
 
 /** Set (change) the input/output sampling rates and resampling ratio 
  * (fractional values in Hz supported).
@@ -244,11 +232,9 @@ void speex_resampler_get_rate(SpeexResamplerState *st,
  * @param in_rate Input sampling rate rounded to the nearest integer (in Hz).
  * @param out_rate Output sampling rate rounded to the nearest integer (in Hz).
  */
-int speex_resampler_set_rate_frac(SpeexResamplerState *st, 
-                                   spx_uint32_t ratio_num, 
-                                   spx_uint32_t ratio_den, 
-                                   spx_uint32_t in_rate, 
-                                   spx_uint32_t out_rate);
+  int speex_resampler_set_rate_frac (SpeexResamplerState * st,
+      spx_uint32_t ratio_num,
+      spx_uint32_t ratio_den, spx_uint32_t in_rate, spx_uint32_t out_rate);
 
 /** Get the current resampling ratio. This will be reduced to the least
  * common denominator.
@@ -256,63 +242,60 @@ int speex_resampler_set_rate_frac(SpeexResamplerState *st,
  * @param ratio_num Numerator of the sampling rate ratio copied
  * @param ratio_den Denominator of the sampling rate ratio copied
  */
-void speex_resampler_get_ratio(SpeexResamplerState *st, 
-                               spx_uint32_t *ratio_num, 
-                               spx_uint32_t *ratio_den);
+  void speex_resampler_get_ratio (SpeexResamplerState * st,
+      spx_uint32_t * ratio_num, spx_uint32_t * ratio_den);
 
 /** Set (change) the conversion quality.
  * @param st Resampler state
  * @param quality Resampling quality between 0 and 10, where 0 has poor 
  * quality and 10 has very high quality.
  */
-int speex_resampler_set_quality(SpeexResamplerState *st, 
-                                 int quality);
+  int speex_resampler_set_quality (SpeexResamplerState * st, int quality);
 
 /** Get the conversion quality.
  * @param st Resampler state
  * @param quality Resampling quality between 0 and 10, where 0 has poor 
  * quality and 10 has very high quality.
  */
-void speex_resampler_get_quality(SpeexResamplerState *st, 
-                                 int *quality);
+  void speex_resampler_get_quality (SpeexResamplerState * st, int *quality);
 
 /** Set (change) the input stride.
  * @param st Resampler state
  * @param stride Input stride
  */
-void speex_resampler_set_input_stride(SpeexResamplerState *st, 
-                                      spx_uint32_t stride);
+  void speex_resampler_set_input_stride (SpeexResamplerState * st,
+      spx_uint32_t stride);
 
 /** Get the input stride.
  * @param st Resampler state
  * @param stride Input stride copied
  */
-void speex_resampler_get_input_stride(SpeexResamplerState *st, 
-                                      spx_uint32_t *stride);
+  void speex_resampler_get_input_stride (SpeexResamplerState * st,
+      spx_uint32_t * stride);
 
 /** Set (change) the output stride.
  * @param st Resampler state
  * @param stride Output stride
  */
-void speex_resampler_set_output_stride(SpeexResamplerState *st, 
-                                      spx_uint32_t stride);
+  void speex_resampler_set_output_stride (SpeexResamplerState * st,
+      spx_uint32_t stride);
 
 /** Get the output stride.
  * @param st Resampler state copied
  * @param stride Output stride
  */
-void speex_resampler_get_output_stride(SpeexResamplerState *st, 
-                                      spx_uint32_t *stride);
+  void speex_resampler_get_output_stride (SpeexResamplerState * st,
+      spx_uint32_t * stride);
 
 /** Get the latency in input samples introduced by the resampler.
  * @param st Resampler state
  */
-int speex_resampler_get_input_latency(SpeexResamplerState *st);
+  int speex_resampler_get_input_latency (SpeexResamplerState * st);
 
 /** Get the latency in output samples introduced by the resampler.
  * @param st Resampler state
  */
-int speex_resampler_get_output_latency(SpeexResamplerState *st);
+  int speex_resampler_get_output_latency (SpeexResamplerState * st);
 
 /** Make sure that the first samples to go out of the resamplers don't have 
  * leading zeros. This is only useful before starting to use a newly created 
@@ -322,18 +305,18 @@ int speex_resampler_get_output_latency(SpeexResamplerState *st);
  * is the same for the first frame).
  * @param st Resampler state
  */
-int speex_resampler_skip_zeros(SpeexResamplerState *st);
+  int speex_resampler_skip_zeros (SpeexResamplerState * st);
 
 /** Reset a resampler so a new (unrelated) stream can be processed.
  * @param st Resampler state
  */
-int speex_resampler_reset_mem(SpeexResamplerState *st);
+  int speex_resampler_reset_mem (SpeexResamplerState * st);
 
 /** Returns the English meaning for an error code
  * @param err Error code
  * @return English string
  */
-const char *speex_resampler_strerror(int err);
+  const char *speex_resampler_strerror (int err);
 
 #ifdef __cplusplus
 }