diff --git a/docs/plugins/inspect/plugin-speexresample.xml b/docs/plugins/inspect/plugin-speexresample.xml deleted file mode 100644 index 40127c494d..0000000000 --- a/docs/plugins/inspect/plugin-speexresample.xml +++ /dev/null @@ -1,34 +0,0 @@ - - speexresample - Resamples audio - ../../gst/speexresample/.libs/libgstspeexresample.so - libgstspeexresample.so - 0.10.8 - LGPL - gst-plugins-bad - GStreamer Bad Plug-ins source release - Unknown package origin - - - speexresample - Audio resampler - Filter/Converter/Audio - Resamples audio - Sebastian Dröge <slomo@circular-chaos.org> - - - src - source - always -
audio/x-raw-float, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ], endianness=(int)1234, width=(int)32; audio/x-raw-int, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ], endianness=(int)1234, width=(int)16, depth=(int)16, signed=(boolean)true
-
- - sink - sink - always -
audio/x-raw-float, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ], endianness=(int)1234, width=(int)32; audio/x-raw-int, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ], endianness=(int)1234, width=(int)16, depth=(int)16, signed=(boolean)true
-
-
-
-
-
\ No newline at end of file diff --git a/gst/speexresample/Makefile.am b/gst/speexresample/Makefile.am deleted file mode 100644 index 3e0c4924ac..0000000000 --- a/gst/speexresample/Makefile.am +++ /dev/null @@ -1,31 +0,0 @@ -plugin_LTLIBRARIES = libgstspeexresample.la - -libgstspeexresample_la_SOURCES = \ - gstspeexresample.c \ - speex_resampler_int.c \ - speex_resampler_float.c - -libgstspeexresample_la_CFLAGS = \ - $(GST_PLUGINS_BASE_CFLAGS) \ - $(GST_BASE_CFLAGS) \ - $(GST_CFLAGS) - -libgstspeexresample_la_LIBADD = \ - $(GST_PLUGINS_BASE_LIBS) \ - $(GST_BASE_LIBS) \ - $(GST_LIBS) \ - -lgstaudio-$(GST_MAJORMINOR) \ - $(LIBM) - -libgstspeexresample_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) - -noinst_HEADERS = \ - arch.h \ - fixed_generic.h \ - gstspeexresample.h \ - speex_resampler.h \ - speex_resampler_wrapper.h - -EXTRA_DIST = \ - resample.c - diff --git a/gst/speexresample/README b/gst/speexresample/README deleted file mode 100644 index 68d8c29028..0000000000 --- a/gst/speexresample/README +++ /dev/null @@ -1,80 +0,0 @@ -resample.c -arch.h -fixed_generic.h -speex_resampler.h - -are taken from http://svn.xiph.org/trunk/speex/ revision 14232. - -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" - #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 -+ - /********* 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 @@ - - #ifdef OUTSIDE_SPEEX - #include --static void * -+#include -+ -+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) - { -- return realloc (ptr, size); -+ return g_realloc (ptr, size); - } --static void -+ -+static inline void - speex_free (void *ptr) - { -- free (ptr); -+ g_free (ptr); - } - - #include "speex_resampler.h" diff --git a/gst/speexresample/arch.h b/gst/speexresample/arch.h deleted file mode 100644 index 3b341f0a08..0000000000 --- a/gst/speexresample/arch.h +++ /dev/null @@ -1,241 +0,0 @@ -/* Copyright (C) 2003 Jean-Marc Valin */ -/** - @file arch.h - @brief Various architecture definitions Speex -*/ -/* - 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 ARCH_H -#define ARCH_H - -#ifndef SPEEX_VERSION -#define SPEEX_MAJOR_VERSION 1 /**< Major Speex version. */ -#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. */ -#endif - -/* A couple test to catch stupid option combinations */ -#ifdef FIXED_POINT - -#ifdef FLOATING_POINT -#error You cannot compile as floating point and fixed point at the same time -#endif -#ifdef _USE_SSE -#error SSE is only for floating-point -#endif -#if ((defined (ARM4_ASM)||defined (ARM4_ASM)) && defined(BFIN_ASM)) || (defined (ARM4_ASM)&&defined(ARM5E_ASM)) -#error Make up your mind. What CPU do you have? -#endif -#ifdef VORBIS_PSYCHO -#error Vorbis-psy model currently not implemented in fixed-point -#endif - -#else - -#ifndef FLOATING_POINT -#error You now need to define either FIXED_POINT or FLOATING_POINT -#endif -#if defined (ARM4_ASM) || defined(ARM5E_ASM) || defined(BFIN_ASM) -#error I suppose you can have a [ARM4/ARM5E/Blackfin] that has float instructions? -#endif -#ifdef FIXED_POINT_DEBUG -#error "Don't you think enabling fixed-point is a good thing to do if you want to debug that?" -#endif - - -#endif - -#ifndef OUTSIDE_SPEEX -#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. */ -#define ABS32(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute 32-bit value. */ -#define MIN32(a,b) ((a) < (b) ? (a) : (b)) /**< Maximum 32-bit value. */ -#define MAX32(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 32-bit value. */ - -#ifdef FIXED_POINT - -typedef spx_int16_t spx_word16_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; -typedef spx_word32_t spx_sig_t; - -#define Q15ONE 32767 - -#define LPC_SCALING 8192 -#define SIG_SCALING 16384 -#define LSP_SCALING 8192. -#define GAMMA_SCALING 32768. -#define GAIN_SCALING 64 -#define GAIN_SCALING_1 0.015625 - -#define LPC_SHIFT 13 -#define LSP_SHIFT 13 -#define SIG_SHIFT 14 -#define GAIN_SHIFT 6 - -#define VERY_SMALL 0 -#define VERY_LARGE32 ((spx_word32_t)2147483647) -#define VERY_LARGE16 ((spx_word16_t)32767) -#define Q15_ONE ((spx_word16_t)32767) - - -#ifdef FIXED_DEBUG -#include "fixed_debug.h" -#else - -#include "fixed_generic.h" - -#ifdef ARM5E_ASM -#include "fixed_arm5e.h" -#elif defined (ARM4_ASM) -#include "fixed_arm4.h" -#elif defined (BFIN_ASM) -#include "fixed_bfin.h" -#endif - -#endif - - -#else - -typedef float spx_mem_t; -typedef float spx_coef_t; -typedef float spx_lsp_t; -typedef float spx_sig_t; -typedef float spx_word16_t; -typedef float spx_word32_t; - -#define Q15ONE 1.0f -#define LPC_SCALING 1.f -#define SIG_SCALING 1.f -#define LSP_SCALING 1.f -#define GAMMA_SCALING 1.f -#define GAIN_SCALING 1.f -#define GAIN_SCALING_1 1.f - - -#define VERY_SMALL 1e-15f -#define VERY_LARGE32 1e15f -#define VERY_LARGE16 1e15f -#define Q15_ONE ((spx_word16_t)1.f) - -#define QCONST16(x,bits) (x) -#define QCONST32(x,bits) (x) - -#define NEG16(x) (-(x)) -#define NEG32(x) (-(x)) -#define EXTRACT16(x) (x) -#define EXTEND32(x) (x) -#define SHR16(a,shift) (a) -#define SHL16(a,shift) (a) -#define SHR32(a,shift) (a) -#define SHL32(a,shift) (a) -#define PSHR16(a,shift) (a) -#define PSHR32(a,shift) (a) -#define VSHR32(a,shift) (a) -#define SATURATE16(x,a) (x) -#define SATURATE32(x,a) (x) - -#define PSHR(a,shift) (a) -#define SHR(a,shift) (a) -#define SHL(a,shift) (a) -#define SATURATE(x,a) (x) - -#define ADD16(a,b) ((a)+(b)) -#define SUB16(a,b) ((a)-(b)) -#define ADD32(a,b) ((a)+(b)) -#define SUB32(a,b) ((a)-(b)) -#define MULT16_16_16(a,b) ((a)*(b)) -#define MULT16_16(a,b) ((spx_word32_t)(a)*(spx_word32_t)(b)) -#define MAC16_16(c,a,b) ((c)+(spx_word32_t)(a)*(spx_word32_t)(b)) - -#define MULT16_32_Q11(a,b) ((a)*(b)) -#define MULT16_32_Q13(a,b) ((a)*(b)) -#define MULT16_32_Q14(a,b) ((a)*(b)) -#define MULT16_32_Q15(a,b) ((a)*(b)) -#define MULT16_32_P15(a,b) ((a)*(b)) - -#define MAC16_32_Q11(c,a,b) ((c)+(a)*(b)) -#define MAC16_32_Q15(c,a,b) ((c)+(a)*(b)) - -#define MAC16_16_Q11(c,a,b) ((c)+(a)*(b)) -#define MAC16_16_Q13(c,a,b) ((c)+(a)*(b)) -#define MAC16_16_P13(c,a,b) ((c)+(a)*(b)) -#define MULT16_16_Q11_32(a,b) ((a)*(b)) -#define MULT16_16_Q13(a,b) ((a)*(b)) -#define MULT16_16_Q14(a,b) ((a)*(b)) -#define MULT16_16_Q15(a,b) ((a)*(b)) -#define MULT16_16_P15(a,b) ((a)*(b)) -#define MULT16_16_P13(a,b) ((a)*(b)) -#define MULT16_16_P14(a,b) ((a)*(b)) - -#define DIV32_16(a,b) (((spx_word32_t)(a))/(spx_word16_t)(b)) -#define PDIV32_16(a,b) (((spx_word32_t)(a))/(spx_word16_t)(b)) -#define DIV32(a,b) (((spx_word32_t)(a))/(spx_word32_t)(b)) -#define PDIV32(a,b) (((spx_word32_t)(a))/(spx_word32_t)(b)) - - -#endif - - -#if defined (CONFIG_TI_C54X) || defined (CONFIG_TI_C55X) - -/* 2 on TI C5x DSP */ -#define BYTES_PER_CHAR 2 -#define BITS_PER_CHAR 16 -#define LOG2_BITS_PER_CHAR 4 - -#else - -#define BYTES_PER_CHAR 1 -#define BITS_PER_CHAR 8 -#define LOG2_BITS_PER_CHAR 3 - -#endif - - - -#ifdef FIXED_DEBUG -long long spx_mips=0; -#endif - - -#endif diff --git a/gst/speexresample/fixed_generic.h b/gst/speexresample/fixed_generic.h deleted file mode 100644 index 2948177c0b..0000000000 --- a/gst/speexresample/fixed_generic.h +++ /dev/null @@ -1,106 +0,0 @@ -/* Copyright (C) 2003 Jean-Marc Valin */ -/** - @file fixed_generic.h - @brief Generic 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_GENERIC_H -#define FIXED_GENERIC_H - -#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 NEG16(x) (-(x)) -#define NEG32(x) (-(x)) -#define EXTRACT16(x) ((spx_word16_t)(x)) -#define EXTEND32(x) ((spx_word32_t)(x)) -#define SHR16(a,shift) ((a) >> (shift)) -#define SHL16(a,shift) ((a) << (shift)) -#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 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 SATURATE(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x))) - - -#define ADD16(a,b) ((spx_word16_t)((spx_word16_t)(a)+(spx_word16_t)(b))) -#define SUB16(a,b) ((spx_word16_t)(a)-(spx_word16_t)(b)) -#define ADD32(a,b) ((spx_word32_t)(a)+(spx_word32_t)(b)) -#define SUB32(a,b) ((spx_word32_t)(a)-(spx_word32_t)(b)) - - -/* result fits in 16 bits */ -#define MULT16_16_16(a,b) ((((spx_word16_t)(a))*((spx_word16_t)(b)))) - -/* (spx_word32_t)(spx_word16_t) gives TI compiler a hint that it's 16x16->32 multiply */ -#define MULT16_16(a,b) (((spx_word32_t)(spx_word16_t)(a))*((spx_word32_t)(spx_word16_t)(b))) - -#define MAC16_16(c,a,b) (ADD32((c),MULT16_16((a),(b)))) -#define MULT16_32_Q12(a,b) ADD32(MULT16_16((a),SHR((b),12)), SHR(MULT16_16((a),((b)&0x00000fff)),12)) -#define MULT16_32_Q13(a,b) ADD32(MULT16_16((a),SHR((b),13)), SHR(MULT16_16((a),((b)&0x00001fff)),13)) -#define MULT16_32_Q14(a,b) ADD32(MULT16_16((a),SHR((b),14)), SHR(MULT16_16((a),((b)&0x00003fff)),14)) - -#define MULT16_32_Q11(a,b) ADD32(MULT16_16((a),SHR((b),11)), SHR(MULT16_16((a),((b)&0x000007ff)),11)) -#define MAC16_32_Q11(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),11)), SHR(MULT16_16((a),((b)&0x000007ff)),11))) - -#define MULT16_32_P15(a,b) ADD32(MULT16_16((a),SHR((b),15)), PSHR(MULT16_16((a),((b)&0x00007fff)),15)) -#define MULT16_32_Q15(a,b) ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15)) -#define MAC16_32_Q15(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15))) - - -#define MAC16_16_Q11(c,a,b) (ADD32((c),SHR(MULT16_16((a),(b)),11))) -#define MAC16_16_Q13(c,a,b) (ADD32((c),SHR(MULT16_16((a),(b)),13))) -#define MAC16_16_P13(c,a,b) (ADD32((c),SHR(ADD32(4096,MULT16_16((a),(b))),13))) - -#define MULT16_16_Q11_32(a,b) (SHR(MULT16_16((a),(b)),11)) -#define MULT16_16_Q13(a,b) (SHR(MULT16_16((a),(b)),13)) -#define MULT16_16_Q14(a,b) (SHR(MULT16_16((a),(b)),14)) -#define MULT16_16_Q15(a,b) (SHR(MULT16_16((a),(b)),15)) - -#define MULT16_16_P13(a,b) (SHR(ADD32(4096,MULT16_16((a),(b))),13)) -#define MULT16_16_P14(a,b) (SHR(ADD32(8192,MULT16_16((a),(b))),14)) -#define MULT16_16_P15(a,b) (SHR(ADD32(16384,MULT16_16((a),(b))),15)) - -#define MUL_16_32_R15(a,bh,bl) ADD32(MULT16_16((a),(bh)), SHR(MULT16_16((a),(bl)),15)) - -#define DIV32_16(a,b) ((spx_word16_t)(((spx_word32_t)(a))/((spx_word16_t)(b)))) -#define PDIV32_16(a,b) ((spx_word16_t)(((spx_word32_t)(a)+((spx_word16_t)(b)>>1))/((spx_word16_t)(b)))) -#define DIV32(a,b) (((spx_word32_t)(a))/((spx_word32_t)(b))) -#define PDIV32(a,b) (((spx_word32_t)(a)+((spx_word16_t)(b)>>1))/((spx_word32_t)(b))) - -#endif diff --git a/gst/speexresample/gstspeexresample.c b/gst/speexresample/gstspeexresample.c deleted file mode 100644 index 096c6b9319..0000000000 --- a/gst/speexresample/gstspeexresample.c +++ /dev/null @@ -1,991 +0,0 @@ -/* GStreamer - * Copyright (C) 1999 Erik Walthinsen - * Copyright (C) 2003,2004 David A. Schleef - * Copyright (C) 2007 Sebastian Dröge - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/** - * SECTION:element-speexresample - * - * speexresample resamples raw audio buffers to different sample rates using - * a configurable windowing function to enhance quality. - * - * - * Example launch line - * |[ - * gst-launch -v filesrc location=sine.ogg ! oggdemux ! vorbisdec ! audioconvert ! speexresample ! audio/x-raw-int, rate=8000 ! alsasink - * ]| Decode an Ogg/Vorbis downsample to 8Khz and play sound through alsa. - * To create the Ogg/Vorbis file refer to the documentation of vorbisenc. - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -#include "gstspeexresample.h" -#include -#include - -GST_DEBUG_CATEGORY (speex_resample_debug); -#define GST_CAT_DEFAULT speex_resample_debug - -enum -{ - PROP_0, - PROP_QUALITY -}; - -#define SUPPORTED_CAPS \ -GST_STATIC_CAPS ( \ - "audio/x-raw-float, " \ - "rate = (int) [ 1, MAX ], " \ - "channels = (int) [ 1, MAX ], " \ - "endianness = (int) BYTE_ORDER, " \ - "width = (int) 32; " \ - "audio/x-raw-int, " \ - "rate = (int) [ 1, MAX ], " \ - "channels = (int) [ 1, MAX ], " \ - "endianness = (int) BYTE_ORDER, " \ - "width = (int) 16, " \ - "depth = (int) 16, " \ - "signed = (boolean) true" \ -) - -static GstStaticPadTemplate gst_speex_resample_sink_template = -GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, GST_PAD_ALWAYS, SUPPORTED_CAPS); - -static GstStaticPadTemplate gst_speex_resample_src_template = -GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, GST_PAD_ALWAYS, SUPPORTED_CAPS); - -static void gst_speex_resample_set_property (GObject * object, - guint prop_id, const GValue * value, GParamSpec * pspec); -static void gst_speex_resample_get_property (GObject * object, - guint prop_id, GValue * value, GParamSpec * pspec); - -/* vmethods */ -static gboolean gst_speex_resample_get_unit_size (GstBaseTransform * base, - GstCaps * caps, guint * size); -static GstCaps *gst_speex_resample_transform_caps (GstBaseTransform * base, - GstPadDirection direction, GstCaps * caps); -static gboolean gst_speex_resample_transform_size (GstBaseTransform * trans, - GstPadDirection direction, GstCaps * incaps, guint insize, - GstCaps * outcaps, guint * outsize); -static gboolean gst_speex_resample_set_caps (GstBaseTransform * base, - GstCaps * incaps, GstCaps * outcaps); -static GstFlowReturn gst_speex_resample_transform (GstBaseTransform * base, - GstBuffer * inbuf, GstBuffer * outbuf); -static gboolean gst_speex_resample_event (GstBaseTransform * base, - GstEvent * event); -static gboolean gst_speex_resample_start (GstBaseTransform * base); -static gboolean gst_speex_resample_stop (GstBaseTransform * base); -static gboolean gst_speex_resample_query (GstPad * pad, GstQuery * query); -static const GstQueryType *gst_speex_resample_query_type (GstPad * pad); - -#define DEBUG_INIT(bla) \ - GST_DEBUG_CATEGORY_INIT (speex_resample_debug, "speex_resample", 0, "audio resampling element"); - -GST_BOILERPLATE_FULL (GstSpeexResample, gst_speex_resample, GstBaseTransform, - GST_TYPE_BASE_TRANSFORM, DEBUG_INIT); - -static void -gst_speex_resample_base_init (gpointer g_class) -{ - GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class); - - gst_element_class_add_pad_template (gstelement_class, - gst_static_pad_template_get (&gst_speex_resample_src_template)); - gst_element_class_add_pad_template (gstelement_class, - gst_static_pad_template_get (&gst_speex_resample_sink_template)); - - gst_element_class_set_details_simple (gstelement_class, "Audio resampler", - "Filter/Converter/Audio", "Resamples audio", - "Sebastian Dröge "); -} - -static void -gst_speex_resample_class_init (GstSpeexResampleClass * klass) -{ - GObjectClass *gobject_class = (GObjectClass *) klass; - - gobject_class->set_property = gst_speex_resample_set_property; - gobject_class->get_property = gst_speex_resample_get_property; - - g_object_class_install_property (gobject_class, PROP_QUALITY, - g_param_spec_int ("quality", "Quality", "Resample quality with 0 being " - "the lowest and 10 being the best", - SPEEX_RESAMPLER_QUALITY_MIN, SPEEX_RESAMPLER_QUALITY_MAX, - SPEEX_RESAMPLER_QUALITY_DEFAULT, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - - GST_BASE_TRANSFORM_CLASS (klass)->start = - GST_DEBUG_FUNCPTR (gst_speex_resample_start); - GST_BASE_TRANSFORM_CLASS (klass)->stop = - GST_DEBUG_FUNCPTR (gst_speex_resample_stop); - GST_BASE_TRANSFORM_CLASS (klass)->transform_size = - GST_DEBUG_FUNCPTR (gst_speex_resample_transform_size); - GST_BASE_TRANSFORM_CLASS (klass)->get_unit_size = - GST_DEBUG_FUNCPTR (gst_speex_resample_get_unit_size); - GST_BASE_TRANSFORM_CLASS (klass)->transform_caps = - GST_DEBUG_FUNCPTR (gst_speex_resample_transform_caps); - GST_BASE_TRANSFORM_CLASS (klass)->set_caps = - GST_DEBUG_FUNCPTR (gst_speex_resample_set_caps); - GST_BASE_TRANSFORM_CLASS (klass)->transform = - GST_DEBUG_FUNCPTR (gst_speex_resample_transform); - GST_BASE_TRANSFORM_CLASS (klass)->event = - GST_DEBUG_FUNCPTR (gst_speex_resample_event); - - GST_BASE_TRANSFORM_CLASS (klass)->passthrough_on_same_caps = TRUE; -} - -static void -gst_speex_resample_init (GstSpeexResample * resample, - GstSpeexResampleClass * klass) -{ - GstBaseTransform *trans = GST_BASE_TRANSFORM (resample); - - resample->quality = SPEEX_RESAMPLER_QUALITY_DEFAULT; - - resample->need_discont = FALSE; - - gst_pad_set_query_function (trans->srcpad, gst_speex_resample_query); - gst_pad_set_query_type_function (trans->srcpad, - gst_speex_resample_query_type); -} - -/* vmethods */ -static gboolean -gst_speex_resample_start (GstBaseTransform * base) -{ - GstSpeexResample *resample = GST_SPEEX_RESAMPLE (base); - - resample->ts_offset = -1; - resample->offset = -1; - resample->next_ts = -1; - - return TRUE; -} - -static gboolean -gst_speex_resample_stop (GstBaseTransform * base) -{ - GstSpeexResample *resample = GST_SPEEX_RESAMPLE (base); - - if (resample->state) { - resample_resampler_destroy (resample->state); - resample->state = NULL; - } - - gst_caps_replace (&resample->sinkcaps, NULL); - gst_caps_replace (&resample->srccaps, NULL); - - return TRUE; -} - -static gboolean -gst_speex_resample_get_unit_size (GstBaseTransform * base, GstCaps * caps, - guint * size) -{ - gint width, channels; - GstStructure *structure; - gboolean ret; - - g_return_val_if_fail (size != NULL, FALSE); - - /* this works for both float and int */ - structure = gst_caps_get_structure (caps, 0); - ret = gst_structure_get_int (structure, "width", &width); - ret &= gst_structure_get_int (structure, "channels", &channels); - g_return_val_if_fail (ret, FALSE); - - *size = width * channels / 8; - - return TRUE; -} - -static GstCaps * -gst_speex_resample_transform_caps (GstBaseTransform * base, - GstPadDirection direction, GstCaps * caps) -{ - GstCaps *res; - GstStructure *structure; - - /* transform caps gives one single caps so we can just replace - * the rate property with our range. */ - res = gst_caps_copy (caps); - structure = gst_caps_get_structure (res, 0); - gst_structure_set (structure, "rate", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL); - - return res; -} - -static SpeexResamplerState * -gst_speex_resample_init_state (guint channels, guint inrate, guint outrate, - guint quality, gboolean fp) -{ - SpeexResamplerState *ret = NULL; - gint err = RESAMPLER_ERR_SUCCESS; - - if (fp) - ret = - resample_float_resampler_init (channels, inrate, outrate, quality, - &err); - else - ret = - resample_int_resampler_init (channels, inrate, outrate, quality, &err); - - if (err != RESAMPLER_ERR_SUCCESS) { - GST_ERROR ("Failed to create resampler state: %s", - resample_resampler_strerror (err)); - return NULL; - } - - if (fp) - resample_float_resampler_skip_zeros (ret); - else - resample_int_resampler_skip_zeros (ret); - - return ret; -} - -static gboolean -gst_speex_resample_update_state (GstSpeexResample * resample, gint channels, - gint inrate, gint outrate, gint quality, gboolean fp) -{ - gboolean ret = TRUE; - gboolean updated_latency = FALSE; - - updated_latency = (resample->inrate != inrate - || quality != resample->quality) && resample->state != NULL; - - if (resample->state == NULL) { - ret = TRUE; - } else if (resample->channels != channels || fp != resample->fp) { - resample_resampler_destroy (resample->state); - resample->state = - gst_speex_resample_init_state (channels, inrate, outrate, quality, fp); - - ret = (resample->state != NULL); - } else if (resample->inrate != inrate || resample->outrate != outrate) { - gint err = RESAMPLER_ERR_SUCCESS; - - if (fp) - err = - resample_float_resampler_set_rate (resample->state, inrate, outrate); - else - err = resample_int_resampler_set_rate (resample->state, inrate, outrate); - - if (err != RESAMPLER_ERR_SUCCESS) - GST_ERROR ("Failed to update rate: %s", - resample_resampler_strerror (err)); - - ret = (err == RESAMPLER_ERR_SUCCESS); - } else if (quality != resample->quality) { - gint err = RESAMPLER_ERR_SUCCESS; - - if (fp) - err = resample_float_resampler_set_quality (resample->state, quality); - else - err = resample_int_resampler_set_quality (resample->state, quality); - - if (err != RESAMPLER_ERR_SUCCESS) - GST_ERROR ("Failed to update quality: %s", - resample_resampler_strerror (err)); - - ret = (err == RESAMPLER_ERR_SUCCESS); - } - - resample->channels = channels; - resample->fp = fp; - resample->quality = quality; - resample->inrate = inrate; - resample->outrate = outrate; - - if (updated_latency) - gst_element_post_message (GST_ELEMENT (resample), - gst_message_new_latency (GST_OBJECT (resample))); - - return ret; -} - -static void -gst_speex_resample_reset_state (GstSpeexResample * resample) -{ - if (resample->state && resample->fp) - resample_float_resampler_reset_mem (resample->state); - else if (resample->state && !resample->fp) - resample_int_resampler_reset_mem (resample->state); -} - -static gboolean -gst_speex_resample_parse_caps (GstCaps * incaps, - GstCaps * outcaps, gint * channels, gint * inrate, gint * outrate, - gboolean * fp) -{ - GstStructure *structure; - gboolean ret; - gint myinrate, myoutrate, mychannels; - gboolean myfp; - - GST_DEBUG ("incaps %" GST_PTR_FORMAT ", outcaps %" - GST_PTR_FORMAT, incaps, outcaps); - - structure = gst_caps_get_structure (incaps, 0); - - if (g_str_equal (gst_structure_get_name (structure), "audio/x-raw-float")) - myfp = TRUE; - else - myfp = FALSE; - - ret = gst_structure_get_int (structure, "rate", &myinrate); - ret &= gst_structure_get_int (structure, "channels", &mychannels); - if (!ret) - goto no_in_rate_channels; - - structure = gst_caps_get_structure (outcaps, 0); - ret = gst_structure_get_int (structure, "rate", &myoutrate); - if (!ret) - goto no_out_rate; - - if (channels) - *channels = mychannels; - if (inrate) - *inrate = myinrate; - if (outrate) - *outrate = myoutrate; - - if (fp) - *fp = myfp; - - return TRUE; - - /* ERRORS */ -no_in_rate_channels: - { - GST_DEBUG ("could not get input rate and channels"); - return FALSE; - } -no_out_rate: - { - GST_DEBUG ("could not get output rate"); - return FALSE; - } -} - -static gboolean -gst_speex_resample_transform_size (GstBaseTransform * base, - GstPadDirection direction, GstCaps * caps, guint size, GstCaps * othercaps, - guint * othersize) -{ - GstSpeexResample *resample = GST_SPEEX_RESAMPLE (base); - SpeexResamplerState *state; - GstCaps *srccaps, *sinkcaps; - gboolean use_internal = FALSE; /* whether we use the internal state */ - gboolean ret = TRUE; - guint32 ratio_den, ratio_num; - gboolean fp; - - GST_LOG ("asked to transform size %d in direction %s", - size, direction == GST_PAD_SINK ? "SINK" : "SRC"); - if (direction == GST_PAD_SINK) { - sinkcaps = caps; - srccaps = othercaps; - } else { - sinkcaps = othercaps; - srccaps = caps; - } - - /* if the caps are the ones that _set_caps got called with; we can use - * our own state; otherwise we'll have to create a state */ - if (resample->state && gst_caps_is_equal (sinkcaps, resample->sinkcaps) && - gst_caps_is_equal (srccaps, resample->srccaps)) { - use_internal = TRUE; - state = resample->state; - fp = resample->fp; - } else { - gint inrate, outrate, channels; - - GST_DEBUG ("Can't use internal state, creating state"); - - ret = - gst_speex_resample_parse_caps (caps, othercaps, &channels, &inrate, - &outrate, &fp); - - if (!ret) { - GST_ERROR ("Wrong caps"); - return FALSE; - } - - state = gst_speex_resample_init_state (channels, inrate, outrate, 0, TRUE); - if (!state) - return FALSE; - } - - if (resample->fp || use_internal) - resample_float_resampler_get_ratio (state, &ratio_num, &ratio_den); - else - resample_int_resampler_get_ratio (state, &ratio_num, &ratio_den); - - if (direction == GST_PAD_SINK) { - gint fac = (fp) ? 4 : 2; - - /* asked to convert size of an incoming buffer */ - size /= fac; - *othersize = (size * ratio_den + (ratio_num >> 1)) / ratio_num; - *othersize *= fac; - size *= fac; - } else { - gint fac = (fp) ? 4 : 2; - - /* asked to convert size of an outgoing buffer */ - size /= fac; - *othersize = (size * ratio_num + (ratio_den >> 1)) / ratio_den; - *othersize *= fac; - size *= fac; - } - - GST_LOG ("transformed size %d to %d", size, *othersize); - - if (!use_internal) - resample_resampler_destroy (state); - - return ret; -} - -static gboolean -gst_speex_resample_set_caps (GstBaseTransform * base, GstCaps * incaps, - GstCaps * outcaps) -{ - gboolean ret; - gint inrate = 0, outrate = 0, channels = 0; - gboolean fp = FALSE; - GstSpeexResample *resample = GST_SPEEX_RESAMPLE (base); - - GST_LOG ("incaps %" GST_PTR_FORMAT ", outcaps %" - GST_PTR_FORMAT, incaps, outcaps); - - ret = gst_speex_resample_parse_caps (incaps, outcaps, - &channels, &inrate, &outrate, &fp); - - g_return_val_if_fail (ret, FALSE); - - ret = - gst_speex_resample_update_state (resample, channels, inrate, outrate, - resample->quality, fp); - - g_return_val_if_fail (ret, FALSE); - - /* save caps so we can short-circuit in the size_transform if the caps - * are the same */ - gst_caps_replace (&resample->sinkcaps, incaps); - gst_caps_replace (&resample->srccaps, outcaps); - - return TRUE; -} - -static void -gst_speex_resample_push_drain (GstSpeexResample * resample) -{ - GstBuffer *buf; - GstBaseTransform *trans = GST_BASE_TRANSFORM (resample); - GstFlowReturn res; - gint outsize; - guint out_len, out_processed; - gint err; - - if (!resample->state) - return; - - if (resample->fp) { - guint num, den; - - resample_float_resampler_get_ratio (resample->state, &num, &den); - - out_len = resample_float_resampler_get_input_latency (resample->state); - out_len = out_processed = (out_len * den + (num >> 1)) / num; - outsize = 4 * out_len * resample->channels; - } else { - guint num, den; - - resample_int_resampler_get_ratio (resample->state, &num, &den); - - out_len = resample_int_resampler_get_input_latency (resample->state); - out_len = out_processed = (out_len * den + (num >> 1)) / num; - outsize = 2 * out_len * resample->channels; - } - - res = gst_pad_alloc_buffer (trans->srcpad, GST_BUFFER_OFFSET_NONE, outsize, - GST_PAD_CAPS (trans->srcpad), &buf); - - if (G_UNLIKELY (res != GST_FLOW_OK)) { - GST_WARNING ("failed allocating buffer of %d bytes", outsize); - return; - } - - if (resample->fp) { - guint len = resample_float_resampler_get_input_latency (resample->state); - - err = - resample_float_resampler_process_interleaved_float (resample->state, - NULL, &len, (gfloat *) GST_BUFFER_DATA (buf), &out_processed); - } else { - guint len = resample_int_resampler_get_input_latency (resample->state); - - err = - resample_int_resampler_process_interleaved_int (resample->state, NULL, - &len, (gint16 *) GST_BUFFER_DATA (buf), &out_processed); - } - - if (err != RESAMPLER_ERR_SUCCESS) { - GST_WARNING ("Failed to process drain: %s", - resample_resampler_strerror (err)); - gst_buffer_unref (buf); - return; - } - - if (out_processed == 0) { - GST_WARNING ("Failed to get drain, dropping buffer"); - gst_buffer_unref (buf); - return; - } - - GST_BUFFER_OFFSET (buf) = resample->offset; - GST_BUFFER_TIMESTAMP (buf) = resample->next_ts; - GST_BUFFER_SIZE (buf) = - out_processed * resample->channels * ((resample->fp) ? 4 : 2); - - if (resample->ts_offset != -1) { - resample->offset += out_processed; - resample->ts_offset += out_processed; - resample->next_ts = - GST_FRAMES_TO_CLOCK_TIME (resample->ts_offset, resample->outrate); - GST_BUFFER_OFFSET_END (buf) = resample->offset; - - /* we calculate DURATION as the difference between "next" timestamp - * and current timestamp so we ensure a contiguous stream, instead of - * having rounding errors. */ - GST_BUFFER_DURATION (buf) = resample->next_ts - GST_BUFFER_TIMESTAMP (buf); - } else { - /* no valid offset know, we can still sortof calculate the duration though */ - GST_BUFFER_DURATION (buf) = - GST_FRAMES_TO_CLOCK_TIME (out_processed, resample->outrate); - } - - GST_LOG ("Pushing drain buffer of %u bytes with timestamp %" GST_TIME_FORMAT - " duration %" GST_TIME_FORMAT " offset %" G_GUINT64_FORMAT - " offset_end %" G_GUINT64_FORMAT, - GST_BUFFER_SIZE (buf), - GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), - GST_TIME_ARGS (GST_BUFFER_DURATION (buf)), - GST_BUFFER_OFFSET (buf), GST_BUFFER_OFFSET_END (buf)); - - res = gst_pad_push (trans->srcpad, buf); - - if (res != GST_FLOW_OK) - GST_WARNING ("Failed to push drain"); - - return; -} - -static gboolean -gst_speex_resample_event (GstBaseTransform * base, GstEvent * event) -{ - GstSpeexResample *resample = GST_SPEEX_RESAMPLE (base); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_FLUSH_START: - break; - case GST_EVENT_FLUSH_STOP: - gst_speex_resample_reset_state (resample); - resample->ts_offset = -1; - resample->next_ts = -1; - resample->offset = -1; - case GST_EVENT_NEWSEGMENT: - gst_speex_resample_push_drain (resample); - gst_speex_resample_reset_state (resample); - resample->ts_offset = -1; - resample->next_ts = -1; - resample->offset = -1; - break; - case GST_EVENT_EOS:{ - gst_speex_resample_push_drain (resample); - gst_speex_resample_reset_state (resample); - break; - } - default: - break; - } - parent_class->event (base, event); - - return TRUE; -} - -static gboolean -gst_speex_resample_check_discont (GstSpeexResample * resample, - GstClockTime timestamp) -{ - if (timestamp != GST_CLOCK_TIME_NONE && - resample->prev_ts != GST_CLOCK_TIME_NONE && - resample->prev_duration != GST_CLOCK_TIME_NONE && - timestamp != resample->prev_ts + resample->prev_duration) { - /* Potentially a discontinuous buffer. However, it turns out that many - * elements generate imperfect streams due to rounding errors, so we permit - * a small error (up to one sample) without triggering a filter - * flush/restart (if triggered incorrectly, this will be audible) */ - GstClockTimeDiff diff = timestamp - - (resample->prev_ts + resample->prev_duration); - - if (ABS (diff) > GST_SECOND / resample->inrate) { - GST_WARNING ("encountered timestamp discontinuity of %" G_GINT64_FORMAT, - diff); - return TRUE; - } - } - - return FALSE; -} - -static void -gst_speex_fix_output_buffer (GstSpeexResample * resample, GstBuffer * outbuf, - guint diff) -{ - GstClockTime timediff = GST_FRAMES_TO_CLOCK_TIME (diff, resample->outrate); - - GST_LOG ("Adjusting buffer by %d samples", diff); - - GST_BUFFER_DURATION (outbuf) -= timediff; - GST_BUFFER_SIZE (outbuf) -= - diff * ((resample->fp) ? 4 : 2) * resample->channels; - - if (resample->ts_offset != -1) { - GST_BUFFER_OFFSET_END (outbuf) -= diff; - resample->offset -= diff; - resample->ts_offset -= diff; - resample->next_ts = - GST_FRAMES_TO_CLOCK_TIME (resample->ts_offset, resample->outrate); - } -} - -static GstFlowReturn -gst_speex_resample_process (GstSpeexResample * resample, GstBuffer * inbuf, - GstBuffer * outbuf) -{ - guint32 in_len, in_processed; - guint32 out_len, out_processed; - gint err = RESAMPLER_ERR_SUCCESS; - - in_len = GST_BUFFER_SIZE (inbuf) / resample->channels; - out_len = GST_BUFFER_SIZE (outbuf) / resample->channels; - - if (resample->fp) { - in_len /= 4; - out_len /= 4; - } else { - in_len /= 2; - out_len /= 2; - } - - in_processed = in_len; - out_processed = out_len; - - if (resample->fp) - err = resample_float_resampler_process_interleaved_float (resample->state, - (const gfloat *) GST_BUFFER_DATA (inbuf), &in_processed, - (gfloat *) GST_BUFFER_DATA (outbuf), &out_processed); - else - err = resample_int_resampler_process_interleaved_int (resample->state, - (const gint16 *) GST_BUFFER_DATA (inbuf), &in_processed, - (gint16 *) GST_BUFFER_DATA (outbuf), &out_processed); - - if (in_len != in_processed) - GST_WARNING ("Converted %d of %d input samples", in_processed, in_len); - - if (out_len != out_processed) { - /* One sample difference is allowed as this will happen - * because of rounding errors */ - if (out_processed == 0) { - GST_DEBUG ("Converted to 0 samples, buffer dropped"); - - if (resample->ts_offset != -1) { - GST_BUFFER_OFFSET_END (outbuf) -= out_len; - resample->offset -= out_len; - resample->ts_offset -= out_len; - resample->next_ts = - GST_FRAMES_TO_CLOCK_TIME (resample->ts_offset, resample->outrate); - } - - return GST_BASE_TRANSFORM_FLOW_DROPPED; - } else if (out_len - out_processed != 1) - GST_WARNING ("Converted to %d instead of %d output samples", - out_processed, out_len); - if (out_len > out_processed) { - gst_speex_fix_output_buffer (resample, outbuf, out_len - out_processed); - } else { - GST_ERROR ("Wrote more output than allocated!"); - return GST_FLOW_ERROR; - } - } - - if (err != RESAMPLER_ERR_SUCCESS) { - GST_ERROR ("Failed to convert data: %s", resample_resampler_strerror (err)); - return GST_FLOW_ERROR; - } else { - GST_LOG ("Converted to buffer of %u bytes with timestamp %" GST_TIME_FORMAT - ", duration %" GST_TIME_FORMAT ", offset %" G_GUINT64_FORMAT - ", offset_end %" G_GUINT64_FORMAT, - GST_BUFFER_SIZE (outbuf), - GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)), - GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)), - GST_BUFFER_OFFSET (outbuf), GST_BUFFER_OFFSET_END (outbuf)); - return GST_FLOW_OK; - } -} - -static GstFlowReturn -gst_speex_resample_transform (GstBaseTransform * base, GstBuffer * inbuf, - GstBuffer * outbuf) -{ - GstSpeexResample *resample = GST_SPEEX_RESAMPLE (base); - guint8 *data; - gulong size; - GstClockTime timestamp; - gint outsamples; - - if (resample->state == NULL) - if (!(resample->state = gst_speex_resample_init_state (resample->channels, - resample->inrate, resample->outrate, resample->quality, - resample->fp))) - return GST_FLOW_ERROR; - - data = GST_BUFFER_DATA (inbuf); - size = GST_BUFFER_SIZE (inbuf); - timestamp = GST_BUFFER_TIMESTAMP (inbuf); - - GST_LOG ("transforming buffer of %ld bytes, ts %" - GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT ", offset %" - G_GINT64_FORMAT ", offset_end %" G_GINT64_FORMAT, - size, GST_TIME_ARGS (timestamp), - GST_TIME_ARGS (GST_BUFFER_DURATION (inbuf)), - GST_BUFFER_OFFSET (inbuf), GST_BUFFER_OFFSET_END (inbuf)); - - /* check for timestamp discontinuities and flush/reset if needed */ - if (G_UNLIKELY (gst_speex_resample_check_discont (resample, timestamp) - || GST_BUFFER_IS_DISCONT (inbuf))) { - /* Flush internal samples */ - gst_speex_resample_reset_state (resample); - /* Inform downstream element about discontinuity */ - resample->need_discont = TRUE; - /* We want to recalculate the offset */ - resample->ts_offset = -1; - } - - outsamples = GST_BUFFER_SIZE (outbuf) / resample->channels; - outsamples /= (resample->fp) ? 4 : 2; - - if (resample->ts_offset == -1) { - /* if we don't know the initial offset yet, calculate it based on the - * input timestamp. */ - if (GST_CLOCK_TIME_IS_VALID (timestamp)) { - GstClockTime stime; - - /* offset used to calculate the timestamps. We use the sample offset for - * this to make it more accurate. We want the first buffer to have the - * same timestamp as the incoming timestamp. */ - resample->next_ts = timestamp; - resample->ts_offset = - GST_CLOCK_TIME_TO_FRAMES (timestamp, resample->outrate); - /* offset used to set as the buffer offset, this offset is always - * relative to the stream time, note that timestamp is not... */ - stime = (timestamp - base->segment.start) + base->segment.time; - resample->offset = GST_CLOCK_TIME_TO_FRAMES (stime, resample->outrate); - } - } - resample->prev_ts = timestamp; - resample->prev_duration = GST_BUFFER_DURATION (inbuf); - - GST_BUFFER_OFFSET (outbuf) = resample->offset; - GST_BUFFER_TIMESTAMP (outbuf) = resample->next_ts; - - if (resample->ts_offset != -1) { - resample->offset += outsamples; - resample->ts_offset += outsamples; - resample->next_ts = - GST_FRAMES_TO_CLOCK_TIME (resample->ts_offset, resample->outrate); - GST_BUFFER_OFFSET_END (outbuf) = resample->offset; - - /* we calculate DURATION as the difference between "next" timestamp - * and current timestamp so we ensure a contiguous stream, instead of - * having rounding errors. */ - GST_BUFFER_DURATION (outbuf) = resample->next_ts - - GST_BUFFER_TIMESTAMP (outbuf); - } else { - /* no valid offset know, we can still sortof calculate the duration though */ - GST_BUFFER_DURATION (outbuf) = - GST_FRAMES_TO_CLOCK_TIME (outsamples, resample->outrate); - } - - if (G_UNLIKELY (resample->need_discont)) { - GST_DEBUG ("marking this buffer with the DISCONT flag"); - GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT); - resample->need_discont = FALSE; - } - - return gst_speex_resample_process (resample, inbuf, outbuf); -} - -static gboolean -gst_speex_resample_query (GstPad * pad, GstQuery * query) -{ - GstSpeexResample *resample = GST_SPEEX_RESAMPLE (gst_pad_get_parent (pad)); - GstBaseTransform *trans = GST_BASE_TRANSFORM (resample); - gboolean res = TRUE; - - switch (GST_QUERY_TYPE (query)) { - case GST_QUERY_LATENCY: - { - GstClockTime min, max; - gboolean live; - guint64 latency; - GstPad *peer; - gint rate = resample->inrate; - gint resampler_latency; - - if (resample->state && resample->fp) - resampler_latency = - resample_float_resampler_get_input_latency (resample->state); - else if (resample->state && !resample->fp) - resampler_latency = - resample_int_resampler_get_input_latency (resample->state); - else - resampler_latency = 0; - - if (gst_base_transform_is_passthrough (trans)) - resampler_latency = 0; - - if ((peer = gst_pad_get_peer (trans->sinkpad))) { - if ((res = gst_pad_query (peer, query))) { - gst_query_parse_latency (query, &live, &min, &max); - - GST_DEBUG ("Peer latency: min %" - GST_TIME_FORMAT " max %" GST_TIME_FORMAT, - GST_TIME_ARGS (min), GST_TIME_ARGS (max)); - - /* add our own latency */ - if (rate != 0 && resampler_latency != 0) - latency = - gst_util_uint64_scale (resampler_latency, GST_SECOND, rate); - else - latency = 0; - - GST_DEBUG ("Our latency: %" GST_TIME_FORMAT, GST_TIME_ARGS (latency)); - - min += latency; - if (max != GST_CLOCK_TIME_NONE) - max += latency; - - GST_DEBUG ("Calculated total latency : min %" - GST_TIME_FORMAT " max %" GST_TIME_FORMAT, - GST_TIME_ARGS (min), GST_TIME_ARGS (max)); - - gst_query_set_latency (query, live, min, max); - } - gst_object_unref (peer); - } - break; - } - default: - res = gst_pad_query_default (pad, query); - break; - } - gst_object_unref (resample); - return res; -} - -static const GstQueryType * -gst_speex_resample_query_type (GstPad * pad) -{ - static const GstQueryType types[] = { - GST_QUERY_LATENCY, - 0 - }; - - return types; -} - -static void -gst_speex_resample_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstSpeexResample *resample; - - resample = GST_SPEEX_RESAMPLE (object); - - switch (prop_id) { - case PROP_QUALITY: - resample->quality = g_value_get_int (value); - GST_DEBUG ("new quality %d", resample->quality); - - gst_speex_resample_update_state (resample, resample->channels, - resample->inrate, resample->outrate, resample->quality, resample->fp); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_speex_resample_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - GstSpeexResample *resample; - - resample = GST_SPEEX_RESAMPLE (object); - - switch (prop_id) { - case PROP_QUALITY: - g_value_set_int (value, resample->quality); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - - -static gboolean -plugin_init (GstPlugin * plugin) -{ - if (!gst_element_register (plugin, "speexresample", GST_RANK_NONE, - GST_TYPE_SPEEX_RESAMPLE)) { - return FALSE; - } - - return TRUE; -} - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "speexresample", - "Resamples audio", plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, - GST_PACKAGE_ORIGIN); diff --git a/gst/speexresample/gstspeexresample.h b/gst/speexresample/gstspeexresample.h deleted file mode 100644 index b5abf0e674..0000000000 --- a/gst/speexresample/gstspeexresample.h +++ /dev/null @@ -1,82 +0,0 @@ -/* GStreamer - * Copyright (C) <1999> Erik Walthinsen - * Copyright (C) <2007> Sebastian Dröge - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - - -#ifndef __SPEEX_RESAMPLE_H__ -#define __SPEEX_RESAMPLE_H__ - -#include -#include - -#include "speex_resampler_wrapper.h" - -G_BEGIN_DECLS - -#define GST_TYPE_SPEEX_RESAMPLE \ - (gst_speex_resample_get_type()) -#define GST_SPEEX_RESAMPLE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SPEEX_RESAMPLE,GstSpeexResample)) -#define GST_SPEEX_RESAMPLE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SPEEX_RESAMPLE,GstSpeexResampleClass)) -#define GST_IS_SPEEX_RESAMPLE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SPEEX_RESAMPLE)) -#define GST_IS_SPEEX_RESAMPLE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SPEEX_RESAMPLE)) - -typedef struct _GstSpeexResample GstSpeexResample; -typedef struct _GstSpeexResampleClass GstSpeexResampleClass; - -/** - * GstSpeexResample: - * - * Opaque data structure. - */ -struct _GstSpeexResample { - GstBaseTransform element; - - /* */ - - GstCaps *srccaps, *sinkcaps; - - gboolean need_discont; - - guint64 offset; - guint64 ts_offset; - GstClockTime next_ts; - GstClockTime prev_ts, prev_duration; - - gboolean fp; - int channels; - int inrate; - int outrate; - int quality; - - SpeexResamplerState *state; -}; - -struct _GstSpeexResampleClass { - GstBaseTransformClass parent_class; -}; - -GType gst_speex_resample_get_type(void); - -G_END_DECLS - -#endif /* __SPEEX_RESAMPLE_H__ */ diff --git a/gst/speexresample/resample.c b/gst/speexresample/resample.c deleted file mode 100644 index 29b95f2341..0000000000 --- a/gst/speexresample/resample.c +++ /dev/null @@ -1,1372 +0,0 @@ -/* Copyright (C) 2007 Jean-Marc Valin - - File: resample.c - Arbitrary resampling code - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - - 3. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. -*/ - -/* - The design goals of this code are: - - Very fast algorithm - - SIMD-friendly algorithm - - Low memory requirement - - Good *perceptual* quality (and not best SNR) - - Warning: This resampler is relatively new. Although I think I got rid of - all the major bugs and I don't expect the API to change anymore, there - may be something I've missed. So use with caution. - - This algorithm is based on this original resampling algorithm: - Smith, Julius O. Digital Audio Resampling Home Page - Center for Computer Research in Music and Acoustics (CCRMA), - Stanford University, 2007. - Web published at http://www-ccrma.stanford.edu/~jos/resample/. - - There is one main difference, though. This resampler uses cubic - interpolation instead of linear interpolation in the above paper. This - makes the table much smaller and makes it possible to compute that table - on a per-stream basis. In turn, being able to tweak the table for each - stream makes it possible to both reduce complexity on simple ratios - (e.g. 2/3), and get rid of the rounding operations in the inner loop. - The latter both reduces CPU time and makes the algorithm more SIMD-friendly. -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef OUTSIDE_SPEEX -#include -#include - -static inline void * -speex_alloc (int size) -{ - return g_malloc0 (size); -} -static inline void * -speex_realloc (void *ptr, int size) -{ - return g_realloc (ptr, size); -} - -static inline void -speex_free (void *ptr) -{ - g_free (ptr); -} - -#include "speex_resampler.h" -#include "arch.h" -#else /* OUTSIDE_SPEEX */ - -#include "speex/speex_resampler.h" -#include "arch.h" -#include "os_support.h" -#endif /* OUTSIDE_SPEEX */ - -#include - -#ifndef M_PI -#define M_PI 3.14159263 -#endif - -#ifdef FIXED_POINT -#define WORD2INT(x) ((x) < -32767 ? -32768 : ((x) > 32766 ? 32767 : (x))) -#else -#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)) - -#ifndef NULL -#define NULL 0 -#endif - -typedef int (*resampler_basic_func) (SpeexResamplerState *, spx_uint32_t, - const spx_word16_t *, spx_uint32_t *, spx_word16_t *, spx_uint32_t *); - -struct SpeexResamplerState_ -{ - spx_uint32_t in_rate; - spx_uint32_t out_rate; - spx_uint32_t num_rate; - spx_uint32_t den_rate; - - int quality; - spx_uint32_t nb_channels; - spx_uint32_t filt_len; - spx_uint32_t mem_alloc_size; - int int_advance; - int frac_advance; - float cutoff; - spx_uint32_t oversample; - int initialised; - int started; - - /* These are per-channel */ - spx_int32_t *last_sample; - spx_uint32_t *samp_frac_num; - spx_uint32_t *magic_samples; - - spx_word16_t *mem; - spx_word16_t *sinc_table; - spx_uint32_t sinc_table_length; - resampler_basic_func resampler_ptr; - - int in_stride; - int out_stride; -}; - -static double kaiser12_table[68] = { - 0.99859849, 1.00000000, 0.99859849, 0.99440475, 0.98745105, 0.97779076, - 0.96549770, 0.95066529, 0.93340547, 0.91384741, 0.89213598, 0.86843014, - 0.84290116, 0.81573067, 0.78710866, 0.75723148, 0.72629970, 0.69451601, - 0.66208321, 0.62920216, 0.59606986, 0.56287762, 0.52980938, 0.49704014, - 0.46473455, 0.43304576, 0.40211431, 0.37206735, 0.34301800, 0.31506490, - 0.28829195, 0.26276832, 0.23854851, 0.21567274, 0.19416736, 0.17404546, - 0.15530766, 0.13794294, 0.12192957, 0.10723616, 0.09382272, 0.08164178, - 0.07063950, 0.06075685, 0.05193064, 0.04409466, 0.03718069, 0.03111947, - 0.02584161, 0.02127838, 0.01736250, 0.01402878, 0.01121463, 0.00886058, - 0.00691064, 0.00531256, 0.00401805, 0.00298291, 0.00216702, 0.00153438, - 0.00105297, 0.00069463, 0.00043489, 0.00025272, 0.00013031, 0.0000527734, - 0.00001000, 0.00000000 -}; - -/* -static double kaiser12_table[36] = { - 0.99440475, 1.00000000, 0.99440475, 0.97779076, 0.95066529, 0.91384741, - 0.86843014, 0.81573067, 0.75723148, 0.69451601, 0.62920216, 0.56287762, - 0.49704014, 0.43304576, 0.37206735, 0.31506490, 0.26276832, 0.21567274, - 0.17404546, 0.13794294, 0.10723616, 0.08164178, 0.06075685, 0.04409466, - 0.03111947, 0.02127838, 0.01402878, 0.00886058, 0.00531256, 0.00298291, - 0.00153438, 0.00069463, 0.00025272, 0.0000527734, 0.00000500, 0.00000000}; -*/ -static double kaiser10_table[36] = { - 0.99537781, 1.00000000, 0.99537781, 0.98162644, 0.95908712, 0.92831446, - 0.89005583, 0.84522401, 0.79486424, 0.74011713, 0.68217934, 0.62226347, - 0.56155915, 0.50119680, 0.44221549, 0.38553619, 0.33194107, 0.28205962, - 0.23636152, 0.19515633, 0.15859932, 0.12670280, 0.09935205, 0.07632451, - 0.05731132, 0.04193980, 0.02979584, 0.02044510, 0.01345224, 0.00839739, - 0.00488951, 0.00257636, 0.00115101, 0.00035515, 0.00000000, 0.00000000 -}; - -static double kaiser8_table[36] = { - 0.99635258, 1.00000000, 0.99635258, 0.98548012, 0.96759014, 0.94302200, - 0.91223751, 0.87580811, 0.83439927, 0.78875245, 0.73966538, 0.68797126, - 0.63451750, 0.58014482, 0.52566725, 0.47185369, 0.41941150, 0.36897272, - 0.32108304, 0.27619388, 0.23465776, 0.19672670, 0.16255380, 0.13219758, - 0.10562887, 0.08273982, 0.06335451, 0.04724088, 0.03412321, 0.02369490, - 0.01563093, 0.00959968, 0.00527363, 0.00233883, 0.00050000, 0.00000000 -}; - -static double kaiser6_table[36] = { - 0.99733006, 1.00000000, 0.99733006, 0.98935595, 0.97618418, 0.95799003, - 0.93501423, 0.90755855, 0.87598009, 0.84068475, 0.80211977, 0.76076565, - 0.71712752, 0.67172623, 0.62508937, 0.57774224, 0.53019925, 0.48295561, - 0.43647969, 0.39120616, 0.34752997, 0.30580127, 0.26632152, 0.22934058, - 0.19505503, 0.16360756, 0.13508755, 0.10953262, 0.08693120, 0.06722600, - 0.05031820, 0.03607231, 0.02432151, 0.01487334, 0.00752000, 0.00000000 -}; - -struct FuncDef -{ - double *table; - int oversample; -}; - -static struct FuncDef _KAISER12 = { kaiser12_table, 64 }; - -#define KAISER12 (&_KAISER12) -/*static struct FuncDef _KAISER12 = {kaiser12_table, 32}; -#define KAISER12 (&_KAISER12)*/ -static struct FuncDef _KAISER10 = { kaiser10_table, 32 }; - -#define KAISER10 (&_KAISER10) -static struct FuncDef _KAISER8 = { kaiser8_table, 32 }; - -#define KAISER8 (&_KAISER8) -static struct FuncDef _KAISER6 = { kaiser6_table, 32 }; - -#define KAISER6 (&_KAISER6) - -struct QualityMapping -{ - int base_length; - int oversample; - float downsample_bandwidth; - float upsample_bandwidth; - struct FuncDef *window_func; -}; - - -/* This table maps conversion quality to internal parameters. There are two - reasons that explain why the up-sampling bandwidth is larger than the - down-sampling bandwidth: - 1) When up-sampling, we can assume that the spectrum is already attenuated - close to the Nyquist rate (from an A/D or a previous resampling filter) - 2) Any aliasing that occurs very close to the Nyquist rate will be masked - by the sinusoids/noise just below the Nyquist rate (guaranteed only for - up-sampling). -*/ -static const struct QualityMapping quality_map[11] = { - {8, 4, 0.830f, 0.860f, KAISER6}, /* Q0 */ - {16, 4, 0.850f, 0.880f, KAISER6}, /* Q1 */ - {32, 4, 0.882f, 0.910f, KAISER6}, /* Q2 *//* 82.3% cutoff ( ~60 dB stop) 6 */ - {48, 8, 0.895f, 0.917f, KAISER8}, /* Q3 *//* 84.9% cutoff ( ~80 dB stop) 8 */ - {64, 8, 0.921f, 0.940f, KAISER8}, /* Q4 *//* 88.7% cutoff ( ~80 dB stop) 8 */ - {80, 16, 0.922f, 0.940f, KAISER10}, /* Q5 *//* 89.1% cutoff (~100 dB stop) 10 */ - {96, 16, 0.940f, 0.945f, KAISER10}, /* Q6 *//* 91.5% cutoff (~100 dB stop) 10 */ - {128, 16, 0.950f, 0.950f, KAISER10}, /* Q7 *//* 93.1% cutoff (~100 dB stop) 10 */ - {160, 16, 0.960f, 0.960f, KAISER10}, /* Q8 *//* 94.5% cutoff (~100 dB stop) 10 */ - {192, 32, 0.968f, 0.968f, KAISER12}, /* Q9 *//* 95.5% cutoff (~100 dB stop) 10 */ - {256, 32, 0.975f, 0.975f, KAISER12}, /* Q10 *//* 96.6% cutoff (~100 dB stop) 10 */ -}; - -/*8,24,40,56,80,104,128,160,200,256,320*/ -static double -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); - /* CSE with handle the repeated powers */ - interp[3] = -0.1666666667 * frac + 0.1666666667 * (frac * frac * frac); - interp[2] = frac + 0.5 * (frac * frac) - 0.5 * (frac * frac * frac); - /*interp[2] = 1.f - 0.5f*frac - frac*frac + 0.5f*frac*frac*frac; */ - interp[0] = - -0.3333333333 * frac + 0.5 * (frac * frac) - - 0.1666666667 * (frac * frac * frac); - /* Just to make sure we don't have rounding problems */ - interp[1] = 1.f - interp[3] - interp[2] - interp[0]; - - /*sum = frac*accum[1] + (1-frac)*accum[2]; */ - return interp[0] * func->table[ind] + interp[1] * func->table[ind + 1] + - interp[2] * func->table[ind + 2] + interp[3] * func->table[ind + 3]; -} - -#if 0 -#include -int -main (int argc, char **argv) -{ - int i; - - for (i = 0; i < 256; i++) { - printf ("%f\n", compute_func (i / 256., KAISER12)); - } - return 0; -} -#endif - -#ifdef FIXED_POINT -/* The slow way of computing a sinc for the table. Should improve that some day */ -static spx_word16_t -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) - return 0; - /*FIXME: Can it really be any slower than this? */ - return WORD2INT (32768. * cutoff * sin (M_PI * xx) / (M_PI * xx) * - compute_func (fabs (2. * x / N), window_func)); -} -#else -/* The slow way of computing a sinc for the table. Should improve that some day */ -static spx_word16_t -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) - return 0; - /*FIXME: Can it really be any slower than this? */ - return cutoff * sin (M_PI * xx) / (M_PI * xx) * compute_func (fabs (2. * x / - N), window_func); -} -#endif - -#ifdef FIXED_POINT -static void -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] = - PSHR32 (MULT16_16 (QCONST16 (-0.16667f, 15), - x) + MULT16_16 (QCONST16 (0.16667f, 15), x3), 15); - interp[1] = - EXTRACT16 (EXTEND32 (x) + SHR32 (SUB32 (EXTEND32 (x2), EXTEND32 (x3)), - 1)); - interp[3] = - PSHR32 (MULT16_16 (QCONST16 (-0.33333f, 15), - x) + MULT16_16 (QCONST16 (.5f, 15), - x2) - MULT16_16 (QCONST16 (0.16667f, 15), x3), 15); - /* Just to make sure we don't have rounding problems */ - interp[2] = Q15_ONE - interp[0] - interp[1] - interp[3]; - if (interp[2] < 32767) - interp[2] += 1; -} -#else -static void -cubic_coef (spx_word16_t frac, 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 */ - interp[0] = -0.16667f * frac + 0.16667f * frac * frac * frac; - interp[1] = frac + 0.5f * frac * frac - 0.5f * frac * frac * frac; - /*interp[2] = 1.f - 0.5f*frac - frac*frac + 0.5f*frac*frac*frac; */ - interp[3] = - -0.33333f * frac + 0.5f * frac * frac - 0.16667f * frac * frac * frac; - /* Just to make sure we don't have rounding problems */ - interp[2] = 1. - interp[0] - interp[1] - interp[3]; -} -#endif - -static int -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; - 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]; - - 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; - - /* 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]); - } - - /* 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; - } - } - - *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; - last_sample++; - } - } - st->last_sample[channel_index] = last_sample; - st->samp_frac_num[channel_index] = samp_frac_num; - return out_sample; -} - -#ifdef FIXED_POINT -#else -/* This is the same as the previous function, except with a double-precision accumulator */ -static int -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; - 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]; - - 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; - - /* We already have all the filter coefficients pre-computed in the table */ - const spx_word16_t *ptr; - - /* 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; - } - } - - *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; - last_sample++; - } - } - st->last_sample[channel_index] = last_sample; - st->samp_frac_num[channel_index] = samp_frac_num; - return out_sample; -} -#endif - -static int -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; - 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]; - - 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 */ - 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; -#ifdef FIXED_POINT - frac = - PDIV32 (SHL32 ((samp_frac_num * st->oversample) % st->den_rate, 15), - st->den_rate); -#else - 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]; - - accum[0] += - MULT16_16 (curr_mem, - st->sinc_table[4 + (j + 1) * st->oversample - offset - 2]); - accum[1] += - MULT16_16 (curr_mem, - st->sinc_table[4 + (j + 1) * st->oversample - offset - 1]); - accum[2] += - MULT16_16 (curr_mem, - st->sinc_table[4 + (j + 1) * st->oversample - offset]); - accum[3] += - MULT16_16 (curr_mem, - 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]); - - *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; - last_sample++; - } - } - st->last_sample[channel_index] = last_sample; - st->samp_frac_num[channel_index] = samp_frac_num; - return out_sample; -} - -#ifdef FIXED_POINT -#else -/* This is the same as the previous function, except with a double-precision accumulator */ -static int -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; - 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]; - - 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]; - - accum[0] += - MULT16_16 (curr_mem, - st->sinc_table[4 + (j + 1) * st->oversample - offset - 2]); - accum[1] += - MULT16_16 (curr_mem, - st->sinc_table[4 + (j + 1) * st->oversample - offset - 1]); - accum[2] += - MULT16_16 (curr_mem, - st->sinc_table[4 + (j + 1) * st->oversample - offset]); - accum[3] += - MULT16_16 (curr_mem, - 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 = - 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; - last_sample++; - } - } - st->last_sample[channel_index] = last_sample; - st->samp_frac_num[channel_index] = samp_frac_num; - return out_sample; -} -#endif - -static void -update_filter (SpeexResamplerState * st) -{ - spx_uint32_t old_length; - - old_length = st->filt_len; - st->oversample = quality_map[st->quality].oversample; - st->filt_len = quality_map[st->quality].base_length; - - if (st->num_rate > st->den_rate) { - /* down-sampling */ - st->cutoff = - quality_map[st->quality].downsample_bandwidth * st->den_rate / - st->num_rate; - /* FIXME: divide the numerator and denominator by a certain amount if they're too large */ - st->filt_len = st->filt_len * st->num_rate / st->den_rate; - /* Round down to make sure we have a multiple of 4 */ - st->filt_len &= (~0x3); - if (2 * st->den_rate < st->num_rate) - st->oversample >>= 1; - if (4 * st->den_rate < st->num_rate) - st->oversample >>= 1; - if (8 * st->den_rate < st->num_rate) - st->oversample >>= 1; - if (16 * st->den_rate < st->num_rate) - st->oversample >>= 1; - if (st->oversample < 1) - st->oversample = 1; - } else { - /* up-sampling */ - st->cutoff = quality_map[st->quality].upsample_bandwidth; - } - - /* 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 * - sizeof (spx_word16_t)); - else if (st->sinc_table_length < st->filt_len * st->den_rate) { - st->sinc_table = - (spx_word16_t *) speex_realloc (st->sinc_table, - st->filt_len * st->den_rate * sizeof (spx_word16_t)); - st->sinc_table_length = st->filt_len * st->den_rate; - } - 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, - ((j - (spx_int32_t) st->filt_len / 2 + 1) - - ((float) i) / st->den_rate), st->filt_len, - quality_map[st->quality].window_func); - } - } -#ifdef FIXED_POINT - st->resampler_ptr = resampler_basic_direct_single; -#else - if (st->quality > 8) - st->resampler_ptr = resampler_basic_direct_double; - else - st->resampler_ptr = resampler_basic_direct_single; -#endif - /*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 + - 8) * sizeof (spx_word16_t)); - else if (st->sinc_table_length < st->filt_len * st->oversample + 8) { - st->sinc_table = - (spx_word16_t *) speex_realloc (st->sinc_table, - (st->filt_len * st->oversample + 8) * sizeof (spx_word16_t)); - st->sinc_table_length = st->filt_len * st->oversample + 8; - } - for (i = -4; i < (spx_int32_t) (st->oversample * st->filt_len + 4); i++) - st->sinc_table[i + 4] = - sinc (st->cutoff, (i / (float) st->oversample - st->filt_len / 2), - st->filt_len, quality_map[st->quality].window_func); -#ifdef FIXED_POINT - st->resampler_ptr = resampler_basic_interpolate_single; -#else - if (st->quality > 8) - st->resampler_ptr = resampler_basic_interpolate_double; - else - st->resampler_ptr = resampler_basic_interpolate_single; -#endif - /*fprintf (stderr, "resampler uses interpolated sinc table and normalised cutoff %f\n", cutoff); */ - } - st->int_advance = st->num_rate / st->den_rate; - st->frac_advance = st->num_rate % st->den_rate; - - - /* Here's the place where we update the filter memory to take into account - the change in filter length. It's probably the messiest part of the code - due to handling of lots of corner cases. */ - if (!st->mem) { - spx_uint32_t i; - - 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++) - 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 = - (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->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) { - 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; - } - 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 */ - - /* FIXME: This is wrong but for now we need it to avoid going over the array bounds */ - olen = old_length + 2 * st->magic_samples[i]; - for (j = old_length - 2 + st->magic_samples[i]; j >= 0; j--) - st->mem[i * st->mem_alloc_size + j + st->magic_samples[i]] = - st->mem[i * old_alloc_size + j]; - for (j = 0; j < st->magic_samples[i]; j++) - st->mem[i * st->mem_alloc_size + j] = 0; - st->magic_samples[i] = 0; - } - if (st->filt_len > olen) { - /* If the new filter length is still bigger than the "augmented" length */ - /* Copy data going backward */ - for (j = 0; j < olen - 1; j++) - st->mem[i * st->mem_alloc_size + (st->filt_len - 2 - j)] = - st->mem[i * st->mem_alloc_size + (olen - 2 - j)]; - /* Then put zeros for lack of anything better */ - for (; j < st->filt_len - 1; j++) - st->mem[i * st->mem_alloc_size + (st->filt_len - 2 - j)] = 0; - /* Adjust last_sample */ - st->last_sample[i] += (st->filt_len - olen) / 2; - } else { - /* Put back some of the magic! */ - st->magic_samples[i] = (olen - st->filt_len) / 2; - for (j = 0; j < st->filt_len - 1 + st->magic_samples[i]; j++) - st->mem[i * st->mem_alloc_size + j] = - st->mem[i * st->mem_alloc_size + j + st->magic_samples[i]]; - } - } - } 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 */ - for (j = 0; j < st->filt_len - 1 + st->magic_samples[i] + old_magic; j++) - st->mem[i * st->mem_alloc_size + j] = - st->mem[i * st->mem_alloc_size + j + st->magic_samples[i]]; - st->magic_samples[i] += old_magic; - } - } - -} - -SpeexResamplerState * -speex_resampler_init (spx_uint32_t nb_channels, spx_uint32_t in_rate, - spx_uint32_t out_rate, int quality, int *err) -{ - return speex_resampler_init_frac (nb_channels, in_rate, out_rate, in_rate, - out_rate, quality, 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) -{ - spx_uint32_t i; - SpeexResamplerState *st; - - if (quality > 10 || quality < 0) { - if (err) - *err = RESAMPLER_ERR_INVALID_ARG; - return NULL; - } - st = (SpeexResamplerState *) speex_alloc (sizeof (SpeexResamplerState)); - st->initialised = 0; - st->started = 0; - st->in_rate = 0; - st->out_rate = 0; - st->num_rate = 0; - st->den_rate = 0; - st->quality = -1; - st->sinc_table_length = 0; - st->mem_alloc_size = 0; - st->filt_len = 0; - st->mem = 0; - st->resampler_ptr = 0; - - st->cutoff = 1.f; - st->nb_channels = nb_channels; - st->in_stride = 1; - st->out_stride = 1; - - /* 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)); - st->samp_frac_num = (spx_uint32_t *) speex_alloc (nb_channels * sizeof (int)); - for (i = 0; i < nb_channels; i++) { - st->last_sample[i] = 0; - st->magic_samples[i] = 0; - st->samp_frac_num[i] = 0; - } - - speex_resampler_set_quality (st, quality); - speex_resampler_set_rate_frac (st, ratio_num, ratio_den, in_rate, out_rate); - - - update_filter (st); - - st->initialised = 1; - if (err) - *err = RESAMPLER_ERR_SUCCESS; - - return st; -} - -void -speex_resampler_destroy (SpeexResamplerState * st) -{ - speex_free (st->mem); - speex_free (st->sinc_table); - speex_free (st->last_sample); - speex_free (st->magic_samples); - speex_free (st->samp_frac_num); - 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) -{ - int j = 0; - int N = st->filt_len; - int out_sample = 0; - spx_word16_t *mem; - spx_uint32_t tmp_out_len = 0; - - 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); - - 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; - 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; - } - 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) -{ - spx_uint32_t i; - int istride_save, ostride_save; - -#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] = 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; - - 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; - } - *in_len -= ilen; - *out_len -= olen; -#endif - return RESAMPLER_ERR_SUCCESS; -} - -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 -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) -{ - return speex_resampler_process_native (st, channel_index, in, in_len, out, - 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) -{ - spx_uint32_t i; - int istride_save, ostride_save; - -#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]); -#else - spx_word16_t x[FIXED_STACK_ALLOC]; - spx_word16_t y[FIXED_STACK_ALLOC]; - spx_uint32_t ilen = *in_len, olen = *out_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] = 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] = WORD2INT (y[i]); - out += ochunk; - in += ichunk; - ilen -= ichunk; - olen -= ochunk; - } - *in_len -= ilen; - *out_len -= olen; -#endif - return RESAMPLER_ERR_SUCCESS; -} -#endif - -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; - for (i = 0; i < st->nb_channels; i++) { - *out_len = bak_len; - if (in != NULL) - speex_resampler_process_float (st, i, in + i, in_len, out + i, out_len); - else - speex_resampler_process_float (st, i, NULL, in_len, out + i, out_len); - } - st->in_stride = istride_save; - st->out_stride = ostride_save; - return RESAMPLER_ERR_SUCCESS; -} - - -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) -{ - 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; - for (i = 0; i < st->nb_channels; i++) { - *out_len = bak_len; - if (in != NULL) - speex_resampler_process_int (st, i, in + i, in_len, out + i, out_len); - else - speex_resampler_process_int (st, i, NULL, in_len, out + i, out_len); - } - st->in_stride = istride_save; - st->out_stride = ostride_save; - return RESAMPLER_ERR_SUCCESS; -} - -int -speex_resampler_set_rate (SpeexResamplerState * st, spx_uint32_t in_rate, - spx_uint32_t out_rate) -{ - return speex_resampler_set_rate_frac (st, in_rate, out_rate, in_rate, - out_rate); -} - -void -speex_resampler_get_rate (SpeexResamplerState * st, spx_uint32_t * in_rate, - spx_uint32_t * out_rate) -{ - *in_rate = st->in_rate; - *out_rate = st->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) -{ - 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; - - old_den = st->den_rate; - st->in_rate = in_rate; - st->out_rate = out_rate; - st->num_rate = ratio_num; - st->den_rate = ratio_den; - /* FIXME: This is terribly inefficient, but who cares (at least for now)? */ - for (fact = 2; fact <= IMIN (st->num_rate, st->den_rate); fact++) { - while ((st->num_rate % fact == 0) && (st->den_rate % fact == 0)) { - st->num_rate /= fact; - st->den_rate /= fact; - } - } - - if (old_den > 0) { - for (i = 0; i < st->nb_channels; i++) { - st->samp_frac_num[i] = st->samp_frac_num[i] * st->den_rate / old_den; - /* Safety net */ - if (st->samp_frac_num[i] >= st->den_rate) - st->samp_frac_num[i] = st->den_rate - 1; - } - } - - if (st->initialised) - update_filter (st); - return RESAMPLER_ERR_SUCCESS; -} - -void -speex_resampler_get_ratio (SpeexResamplerState * st, spx_uint32_t * ratio_num, - spx_uint32_t * ratio_den) -{ - *ratio_num = st->num_rate; - *ratio_den = st->den_rate; -} - -int -speex_resampler_set_quality (SpeexResamplerState * st, int quality) -{ - if (quality > 10 || quality < 0) - return RESAMPLER_ERR_INVALID_ARG; - if (st->quality == quality) - return RESAMPLER_ERR_SUCCESS; - st->quality = quality; - if (st->initialised) - update_filter (st); - return RESAMPLER_ERR_SUCCESS; -} - -void -speex_resampler_get_quality (SpeexResamplerState * st, int *quality) -{ - *quality = st->quality; -} - -void -speex_resampler_set_input_stride (SpeexResamplerState * st, spx_uint32_t stride) -{ - st->in_stride = stride; -} - -void -speex_resampler_get_input_stride (SpeexResamplerState * st, - spx_uint32_t * stride) -{ - *stride = st->in_stride; -} - -void -speex_resampler_set_output_stride (SpeexResamplerState * st, - spx_uint32_t stride) -{ - st->out_stride = stride; -} - -void -speex_resampler_get_output_stride (SpeexResamplerState * st, - spx_uint32_t * stride) -{ - *stride = st->out_stride; -} - -int -speex_resampler_get_input_latency (SpeexResamplerState * st) -{ - return st->filt_len / 2; -} - -int -speex_resampler_get_output_latency (SpeexResamplerState * st) -{ - return ((st->filt_len / 2) * st->den_rate + - (st->num_rate >> 1)) / st->num_rate; -} - -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 -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 * -speex_resampler_strerror (int err) -{ - switch (err) { - case RESAMPLER_ERR_SUCCESS: - return "Success."; - case RESAMPLER_ERR_ALLOC_FAILED: - return "Memory allocation failed."; - case RESAMPLER_ERR_BAD_STATE: - return "Bad resampler state."; - case RESAMPLER_ERR_INVALID_ARG: - return "Invalid argument."; - case RESAMPLER_ERR_PTR_OVERLAP: - return "Input and output buffers overlap."; - default: - return "Unknown error. Bad error code or strange version mismatch."; - } -} diff --git a/gst/speexresample/speex_resampler.h b/gst/speexresample/speex_resampler.h deleted file mode 100644 index ad832c54c8..0000000000 --- a/gst/speexresample/speex_resampler.h +++ /dev/null @@ -1,342 +0,0 @@ -/* Copyright (C) 2007 Jean-Marc Valin - - File: speex_resampler.h - Resampling code - - The design goals of this code are: - - Very fast algorithm - - Low memory requirement - - Good *perceptual* quality (and not best SNR) - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - - 3. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 SPEEX_RESAMPLER_H -#define SPEEX_RESAMPLER_H - -#ifdef OUTSIDE_SPEEX - -#include - -/********* WARNING: MENTAL SANITY ENDS HERE *************/ - -/* If the resampler is defined outside of Speex, we change the symbol names so that - there won't be any clash if linking with Speex later on. */ - -/* #define RANDOM_PREFIX your software name here */ -#ifndef RANDOM_PREFIX -#error "Please define RANDOM_PREFIX (above) to something specific to your project to prevent symbol name clashes" -#endif - -#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 speex_resampler_process_float CAT_PREFIX(RANDOM_PREFIX,_resampler_process_float) -#define speex_resampler_process_int CAT_PREFIX(RANDOM_PREFIX,_resampler_process_int) -#define speex_resampler_process_interleaved_float CAT_PREFIX(RANDOM_PREFIX,_resampler_process_interleaved_float) -#define speex_resampler_process_interleaved_int CAT_PREFIX(RANDOM_PREFIX,_resampler_process_interleaved_int) -#define speex_resampler_set_rate CAT_PREFIX(RANDOM_PREFIX,_resampler_set_rate) -#define speex_resampler_get_rate CAT_PREFIX(RANDOM_PREFIX,_resampler_get_rate) -#define speex_resampler_set_rate_frac CAT_PREFIX(RANDOM_PREFIX,_resampler_set_rate_frac) -#define speex_resampler_get_ratio CAT_PREFIX(RANDOM_PREFIX,_resampler_get_ratio) -#define speex_resampler_set_quality CAT_PREFIX(RANDOM_PREFIX,_resampler_set_quality) -#define speex_resampler_get_quality CAT_PREFIX(RANDOM_PREFIX,_resampler_get_quality) -#define speex_resampler_set_input_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_set_input_stride) -#define speex_resampler_get_input_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_get_input_stride) -#define speex_resampler_set_output_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_set_output_stride) -#define speex_resampler_get_output_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_get_output_stride) -#define speex_resampler_get_input_latency CAT_PREFIX(RANDOM_PREFIX,_resampler_get_input_latency) -#define speex_resampler_get_output_latency CAT_PREFIX(RANDOM_PREFIX,_resampler_get_output_latency) -#define speex_resampler_skip_zeros CAT_PREFIX(RANDOM_PREFIX,_resampler_skip_zeros) -#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 gint16 -#define spx_int32_t gint32 -#define spx_uint16_t guint16 -#define spx_uint32_t guint32 - -#else /* OUTSIDE_SPEEX */ - -#include "speex/speex_types.h" - -#endif /* OUTSIDE_SPEEX */ - -#ifdef __cplusplus -extern "C" { -#endif - -#define SPEEX_RESAMPLER_QUALITY_MAX 10 -#define SPEEX_RESAMPLER_QUALITY_MIN 0 -#define SPEEX_RESAMPLER_QUALITY_DEFAULT 4 -#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 -}; - -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 - * @param in_rate Input sampling rate (integer number of Hz). - * @param out_rate Output sampling rate (integer number of Hz). - * @param quality Resampling quality between 0 and 10, where 0 has poor quality - * and 10 has very high quality. - * @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); - -/** Create a new resampler with fractional input/output rates. The sampling - * rate ratio is an arbitrary rational number with both the numerator and - * denominator being 32-bit integers. - * @param nb_channels Number of channels to be processed - * @param ratio_num Numerator of the sampling rate ratio - * @param ratio_den Denominator of the sampling rate ratio - * @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). - * @param quality Resampling quality between 0 and 10, where 0 has poor quality - * and 10 has very high quality. - * @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); - -/** Destroy a resampler state. - * @param st Resampler state - */ -void speex_resampler_destroy(SpeexResamplerState *st); - -/** Resample a float array. The input and output buffers must *not* overlap. - * @param st Resampler state - * @param channel_index Index of the channel to process for the multi-channel - * base (0 otherwise) - * @param in Input buffer - * @param in_len Number of input samples in the input buffer. Returns the - * number of samples processed - * @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); - -/** Resample an int array. The input and output buffers must *not* overlap. - * @param st Resampler state - * @param channel_index Index of the channel to process for the multi-channel - * base (0 otherwise) - * @param in Input buffer - * @param in_len Number of input samples in the input buffer. Returns the number - * of samples processed - * @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); - -/** Resample an interleaved float array. The input and output buffers must *not* overlap. - * @param st Resampler state - * @param in Input buffer - * @param in_len Number of input samples in the input buffer. Returns the number - * of samples processed. This is all per-channel. - * @param out Output buffer - * @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); - -/** Resample an interleaved int array. The input and output buffers must *not* overlap. - * @param st Resampler state - * @param in Input buffer - * @param in_len Number of input samples in the input buffer. Returns the number - * of samples processed. This is all per-channel. - * @param out Output buffer - * @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); - -/** 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); - -/** 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); - -/** Set (change) the input/output sampling rates and resampling ratio - * (fractional values in Hz supported). - * @param st Resampler state - * @param ratio_num Numerator of the sampling rate ratio - * @param ratio_den Denominator of the sampling rate ratio - * @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); - -/** Get the current resampling ratio. This will be reduced to the least - * common denominator. - * @param st Resampler state - * @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); - -/** 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); - -/** 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); - -/** 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); - -/** 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); - -/** 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); - -/** 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); - -/** Get the latency in input samples introduced by the resampler. - * @param st Resampler state - */ -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); - -/** 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 - * resampler. It is recommended to use that when resampling an audio file, as - * it will generate a file with the same length. For real-time processing, - * it is probably easier not to use this call (so that the output duration - * is the same for the first frame). - * @param st Resampler state - */ -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); - -/** Returns the English meaning for an error code - * @param err Error code - * @return English string - */ -const char *speex_resampler_strerror(int err); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/gst/speexresample/speex_resampler_float.c b/gst/speexresample/speex_resampler_float.c deleted file mode 100644 index 281e52d3a3..0000000000 --- a/gst/speexresample/speex_resampler_float.c +++ /dev/null @@ -1,24 +0,0 @@ -/* GStreamer - * Copyright (C) 2007 Sebastian Dröge - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#define FLOATING_POINT -#define OUTSIDE_SPEEX -#define RANDOM_PREFIX resample_float - -#include "resample.c" diff --git a/gst/speexresample/speex_resampler_int.c b/gst/speexresample/speex_resampler_int.c deleted file mode 100644 index c992f0a64c..0000000000 --- a/gst/speexresample/speex_resampler_int.c +++ /dev/null @@ -1,24 +0,0 @@ -/* GStreamer - * Copyright (C) 2007 Sebastian Dröge - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#define FIXED_POINT 1 -#define OUTSIDE_SPEEX 1 -#define RANDOM_PREFIX resample_int - -#include "resample.c" diff --git a/gst/speexresample/speex_resampler_wrapper.h b/gst/speexresample/speex_resampler_wrapper.h deleted file mode 100644 index 6d7c17d036..0000000000 --- a/gst/speexresample/speex_resampler_wrapper.h +++ /dev/null @@ -1,86 +0,0 @@ -/* GStreamer - * Copyright (C) 2007 Sebastian Dröge - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __SPEEX_RESAMPLER_WRAPPER_H__ -#define __SPEEX_RESAMPLER_WRAPPER_H__ - -#define SPEEX_RESAMPLER_QUALITY_MAX 10 -#define SPEEX_RESAMPLER_QUALITY_MIN 0 -#define SPEEX_RESAMPLER_QUALITY_DEFAULT 4 -#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 -}; - -typedef struct SpeexResamplerState_ SpeexResamplerState; - -SpeexResamplerState *resample_float_resampler_init (guint32 nb_channels, - guint32 in_rate, guint32 out_rate, gint quality, gint * err); -SpeexResamplerState *resample_int_resampler_init (guint32 nb_channels, - guint32 in_rate, guint32 out_rate, gint quality, gint * err); - -#define resample_resampler_destroy resample_int_resampler_destroy -void resample_resampler_destroy (SpeexResamplerState * st); - -int resample_float_resampler_process_interleaved_float (SpeexResamplerState * - st, const gfloat * in, guint32 * in_len, gfloat * out, guint32 * out_len); -int resample_int_resampler_process_interleaved_int (SpeexResamplerState * st, - const gint16 * in, guint32 * in_len, gint16 * out, guint32 * out_len); - -int resample_float_resampler_set_rate (SpeexResamplerState * st, - guint32 in_rate, guint32 out_rate); -int resample_int_resampler_set_rate (SpeexResamplerState * st, - guint32 in_rate, guint32 out_rate); - -void resample_float_resampler_get_rate (SpeexResamplerState * st, - guint32 * in_rate, guint32 * out_rate); -void resample_int_resampler_get_rate (SpeexResamplerState * st, - guint32 * in_rate, guint32 * out_rate); - -void resample_float_resampler_get_ratio (SpeexResamplerState * st, - guint32 * ratio_num, guint32 * ratio_den); -void resample_int_resampler_get_ratio (SpeexResamplerState * st, - guint32 * ratio_num, guint32 * ratio_den); - -int resample_float_resampler_get_input_latency (SpeexResamplerState * st); -int resample_int_resampler_get_input_latency (SpeexResamplerState * st); - -int resample_float_resampler_set_quality (SpeexResamplerState * st, - gint quality); -int resample_int_resampler_set_quality (SpeexResamplerState * st, gint quality); - -int resample_float_resampler_reset_mem (SpeexResamplerState * st); -int resample_int_resampler_reset_mem (SpeexResamplerState * st); - -int resample_float_resampler_skip_zeros (SpeexResamplerState * st); -int resample_int_resampler_skip_zeros (SpeexResamplerState * st); - -#define resample_resampler_strerror resample_int_resampler_strerror -const char *resample_resampler_strerror (gint err); - -#endif /* __SPEEX_RESAMPLER_WRAPPER_H__ */