diff options
Diffstat (limited to 'gst')
-rw-r--r-- | gst/speexresample/README | 87 | ||||
-rw-r--r-- | gst/speexresample/arch.h | 13 | ||||
-rw-r--r-- | gst/speexresample/fixed_arm4.h | 130 | ||||
-rw-r--r-- | gst/speexresample/fixed_arm5e.h | 166 | ||||
-rw-r--r-- | gst/speexresample/fixed_bfin.h | 134 | ||||
-rw-r--r-- | gst/speexresample/fixed_debug.h | 525 | ||||
-rw-r--r-- | gst/speexresample/fixed_generic.h | 4 | ||||
-rw-r--r-- | gst/speexresample/resample.c | 726 | ||||
-rw-r--r-- | gst/speexresample/speex_resampler.h | 149 |
9 files changed, 1397 insertions, 537 deletions
diff --git a/gst/speexresample/README b/gst/speexresample/README index 68d8c290..79e11b32 100644 --- a/gst/speexresample/README +++ b/gst/speexresample/README @@ -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 */ + diff --git a/gst/speexresample/arch.h b/gst/speexresample/arch.h index 3b341f0a..168f28bd 100644 --- a/gst/speexresample/arch.h +++ b/gst/speexresample/arch.h @@ -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 */ @@ -75,12 +75,13 @@ #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 index 00000000..df99a60f --- /dev/null +++ b/gst/speexresample/fixed_arm4.h @@ -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 index 00000000..c995d54b --- /dev/null +++ b/gst/speexresample/fixed_arm5e.h @@ -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 index 00000000..63b3fb4b --- /dev/null +++ b/gst/speexresample/fixed_bfin.h @@ -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 index 00000000..9ee8fa2a --- /dev/null +++ b/gst/speexresample/fixed_debug.h @@ -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 diff --git a/gst/speexresample/fixed_generic.h b/gst/speexresample/fixed_generic.h index 2948177c..3fb096ed 100644 --- a/gst/speexresample/fixed_generic.h +++ b/gst/speexresample/fixed_generic.h @@ -47,14 +47,14 @@ #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))) diff --git a/gst/speexresample/resample.c b/gst/speexresample/resample.c index 29b95f23..ec127aa1 100644 --- a/gst/speexresample/resample.c +++ b/gst/speexresample/resample.c @@ -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 @@ -62,13 +63,17 @@ #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) { diff --git a/gst/speexresample/speex_resampler.h b/gst/speexresample/speex_resampler.h index ad832c54..a00c37c8 100644 --- a/gst/speexresample/speex_resampler.h +++ b/gst/speexresample/speex_resampler.h @@ -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) @@ -83,15 +81,20 @@ #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 } |