Remove old speexresample files.

Original commit message from CVS:
* gst/speexresample/Makefile.am:
* gst/speexresample/README:
* gst/speexresample/arch.h:
* gst/speexresample/fixed_arm4.h:
* gst/speexresample/fixed_arm5e.h:
* gst/speexresample/fixed_bfin.h:
* gst/speexresample/fixed_debug.h:
* gst/speexresample/fixed_generic.h:
* gst/speexresample/gstspeexresample.c:
* gst/speexresample/gstspeexresample.h:
* gst/speexresample/resample.c:
* gst/speexresample/resample_sse.h:
* gst/speexresample/speex_resampler.h:
* gst/speexresample/speex_resampler_double.c:
* gst/speexresample/speex_resampler_float.c:
* gst/speexresample/speex_resampler_int.c:
* gst/speexresample/speex_resampler_wrapper.h:
* tests/check/elements/speexresample.c:
Remove old speexresample files.
This commit is contained in:
Sebastian Dröge 2008-11-27 19:22:42 +00:00
parent bf2d02c1b6
commit d56af9d36d
19 changed files with 930 additions and 3214 deletions

View file

@ -1,3 +1,25 @@
2008-11-27 Sebastian Dröge <sebastian.droege@collabora.co.uk>
* gst/speexresample/Makefile.am:
* gst/speexresample/README:
* gst/speexresample/arch.h:
* gst/speexresample/fixed_arm4.h:
* gst/speexresample/fixed_arm5e.h:
* gst/speexresample/fixed_bfin.h:
* gst/speexresample/fixed_debug.h:
* gst/speexresample/fixed_generic.h:
* gst/speexresample/gstspeexresample.c:
* gst/speexresample/gstspeexresample.h:
* gst/speexresample/resample.c:
* gst/speexresample/resample_sse.h:
* gst/speexresample/speex_resampler.h:
* gst/speexresample/speex_resampler_double.c:
* gst/speexresample/speex_resampler_float.c:
* gst/speexresample/speex_resampler_int.c:
* gst/speexresample/speex_resampler_wrapper.h:
* tests/check/elements/speexresample.c:
Remove old speexresample files.
2008-11-27 Sebastian Dröge <sebastian.droege@collabora.co.uk>
* docs/plugins/inspect/plugin-speexresample.xml:

View file

@ -3,36 +3,29 @@ plugin_LTLIBRARIES = libgstspeexresample.la
libgstspeexresample_la_SOURCES = \
gstspeexresample.c \
speex_resampler_int.c \
speex_resampler_float.c \
speex_resampler_double.c
speex_resampler_float.c
libgstspeexresample_la_CFLAGS = \
$(GST_PLUGINS_BASE_CFLAGS) \
$(GST_BASE_CFLAGS) \
$(GST_CFLAGS) \
$(LIBOIL_CFLAGS)
$(GST_CFLAGS)
libgstspeexresample_la_LIBADD = \
$(GST_PLUGINS_BASE_LIBS) \
$(GST_BASE_LIBS) \
$(GST_LIBS) \
-lgstaudio-$(GST_MAJORMINOR) \
$(LIBOIL_LIBS) \
$(LIBM)
libgstspeexresample_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
libgstspeexresample_la_LIBTOOLFLAGS = --tag=disable-static
noinst_HEADERS = \
arch.h \
fixed_arm4.h \
fixed_arm5e.h \
fixed_bfin.h \
fixed_debug.h \
fixed_generic.h \
gstspeexresample.h \
resample.c \
resample_sse.h \
speex_resampler.h \
speex_resampler_wrapper.h
EXTRA_DIST = \
resample.c

View file

@ -1,76 +1,37 @@
arch.h
fixed_arm4.h
fixed_arm5e.h
fixed_bfin.h
fixed_debug.h
fixed_generic.h
resample.c
speex_resampler.h
resample.c
arch.h
fixed_generic.h
speex_resampler.h
are taken from http://git.xiph.org/speex.git/ as of 2008-10-28.
are taken from http://svn.xiph.org/trunk/speex/ revision 14232.
The only changes are:
--- arch.h 2008-10-28 12:21:37.000000000 +0100
+++ arch.h 2008-10-28 12:27:56.000000000 +0100
@@ -78,7 +78,10 @@
#include "../include/speex/speex_types.h"
--- 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. */
--- resample.c 2008-10-28 12:21:35.000000000 +0100
+++ resample.c 2008-10-28 12:33:46.000000000 +0100
@@ -63,22 +63,27 @@
--- 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 <stdlib.h>
-static void *
+
+#include <glib.h>
+
+#define EXPORT
+
+static inline void *
speex_alloc (int size)
{
- return calloc (size, 1);
+ return g_malloc0 (size);
}
/********* WARNING: MENTAL SANITY ENDS HERE *************/
-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"
@@ -90,7 +95,6 @@
#include "os_support.h"
#endif /* OUTSIDE_SPEEX */
-#include "stack_alloc.h"
#include <math.h>
#ifndef M_PI
--- speex_resampler.h 2008-10-28 12:21:37.000000000 +0100
+++ speex_resampler.h 2008-10-28 12:30:48.000000000 +0100
@@ -77,10 +77,10 @@
/* 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)
@ -82,6 +43,38 @@ The only changes are:
+#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 <stdlib.h>
-static void *
+#include <glib.h>
+
+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"

View file

@ -40,7 +40,7 @@
#define SPEEX_MINOR_VERSION 1 /**< Minor Speex version. */
#define SPEEX_MICRO_VERSION 15 /**< Micro Speex version. */
#define SPEEX_EXTRA_VERSION "" /**< Extra Speex version. */
#define SPEEX_VERSION "speex-1.2beta3" /**< Speex version string. */
#define SPEEX_VERSION "speex-1.2beta4" /**< Speex version string. */
#endif
/* A couple test to catch stupid option combinations */
@ -75,13 +75,12 @@
#endif
#ifndef OUTSIDE_SPEEX
#include "../include/speex/speex_types.h"
#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. */
@ -92,7 +91,7 @@
#ifdef FIXED_POINT
typedef spx_int16_t spx_word16_t;
typedef spx_int32_t spx_word32_t;
typedef spx_int32_t spx_word32_t;
typedef spx_word32_t spx_mem_t;
typedef spx_word16_t spx_coef_t;
typedef spx_word16_t spx_lsp_t;
@ -137,28 +136,6 @@ typedef spx_word32_t spx_sig_t;
#else
#ifdef DOUBLE_PRECISION
typedef double spx_mem_t;
typedef double spx_coef_t;
typedef double spx_lsp_t;
typedef double spx_sig_t;
typedef double spx_word16_t;
typedef double spx_word32_t;
#define Q15ONE 1.0
#define LPC_SCALING 1.
#define SIG_SCALING 1.
#define LSP_SCALING 1.
#define GAMMA_SCALING 1.
#define GAIN_SCALING 1.
#define GAIN_SCALING_1 1.
#define VERY_SMALL 1e-20
#define VERY_LARGE32 1e20
#define VERY_LARGE16 1e20
#define Q15_ONE ((spx_word16_t)1.)
#else /* !DOUBLE_PRECISION */
typedef float spx_mem_t;
typedef float spx_coef_t;
typedef float spx_lsp_t;
@ -179,7 +156,6 @@ typedef float spx_word32_t;
#define VERY_LARGE32 1e15f
#define VERY_LARGE16 1e15f
#define Q15_ONE ((spx_word16_t)1.f)
#endif /* DOUBLE_PRECISION */
#define QCONST16(x,bits) (x)
#define QCONST32(x,bits) (x)
@ -243,11 +219,11 @@ typedef float spx_word32_t;
#if defined (CONFIG_TI_C54X) || defined (CONFIG_TI_C55X)
/* 2 on TI C5x DSP */
#define BYTES_PER_CHAR 2
#define BYTES_PER_CHAR 2
#define BITS_PER_CHAR 16
#define LOG2_BITS_PER_CHAR 4
#else
#else
#define BYTES_PER_CHAR 1
#define BITS_PER_CHAR 8
@ -258,7 +234,7 @@ typedef float spx_word32_t;
#ifdef FIXED_DEBUG
extern long long spx_mips;
long long spx_mips=0;
#endif

View file

@ -1,130 +0,0 @@
/* Copyright (C) 2004 Jean-Marc Valin */
/**
@file fixed_arm4.h
@brief ARM4 fixed-point operations
*/
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of the Xiph.org Foundation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef FIXED_ARM4_H
#define FIXED_ARM4_H
#undef MULT16_32_Q14
static inline spx_word32_t
MULT16_32_Q14 (spx_word16_t x, spx_word32_t y)
{
int res;
int dummy;
asm ("smull %0,%1,%2,%3 \n\t" "mov %0, %0, lsr #14 \n\t" "add %0, %0, %1, lsl #18 \n\t":"=&r" (res),
"=&r"
(dummy)
: "r" (y), "r" ((int) x));
return (res);
}
#undef MULT16_32_Q15
static inline spx_word32_t
MULT16_32_Q15 (spx_word16_t x, spx_word32_t y)
{
int res;
int dummy;
asm ("smull %0,%1,%2,%3 \n\t" "mov %0, %0, lsr #15 \n\t" "add %0, %0, %1, lsl #17 \n\t":"=&r" (res),
"=&r"
(dummy)
: "r" (y), "r" ((int) x));
return (res);
}
#undef DIV32_16
static inline short
DIV32_16 (int a, int b)
{
int res = 0;
int dead1, dead2, dead3, dead4, dead5;
__asm__ __volatile__ ("\teor %5, %0, %1\n"
"\tmovs %4, %0\n"
"\trsbmi %0, %0, #0 \n"
"\tmovs %4, %1\n"
"\trsbmi %1, %1, #0 \n"
"\tmov %4, #1\n"
"\tsubs %3, %0, %1, asl #14 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #14 \n"
"\tsubs %3, %0, %1, asl #13 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #13 \n"
"\tsubs %3, %0, %1, asl #12 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #12 \n"
"\tsubs %3, %0, %1, asl #11 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #11 \n"
"\tsubs %3, %0, %1, asl #10 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #10 \n"
"\tsubs %3, %0, %1, asl #9 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #9 \n"
"\tsubs %3, %0, %1, asl #8 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #8 \n"
"\tsubs %3, %0, %1, asl #7 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #7 \n"
"\tsubs %3, %0, %1, asl #6 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #6 \n"
"\tsubs %3, %0, %1, asl #5 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #5 \n"
"\tsubs %3, %0, %1, asl #4 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #4 \n"
"\tsubs %3, %0, %1, asl #3 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #3 \n"
"\tsubs %3, %0, %1, asl #2 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #2 \n"
"\tsubs %3, %0, %1, asl #1 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #1 \n"
"\tsubs %3, %0, %1 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4 \n"
"\tmovs %5, %5, lsr #31 \n"
"\trsbne %2, %2, #0 \n":"=r" (dead1), "=r" (dead2), "=r" (res),
"=r" (dead3), "=r" (dead4), "=r" (dead5)
:"0" (a), "1" (b), "2" (res)
:"cc");
return res;
}
#endif

View file

@ -1,166 +0,0 @@
/* Copyright (C) 2003 Jean-Marc Valin */
/**
@file fixed_arm5e.h
@brief ARM-tuned fixed-point operations
*/
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of the Xiph.org Foundation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef FIXED_ARM5E_H
#define FIXED_ARM5E_H
#undef MULT16_16
static inline spx_word32_t
MULT16_16 (spx_word16_t x, spx_word16_t y)
{
int res;
asm ("smulbb %0,%1,%2;\n":"=&r" (res)
: "%r" (x), "r" (y));
return (res);
}
#undef MAC16_16
static inline spx_word32_t
MAC16_16 (spx_word32_t a, spx_word16_t x, spx_word32_t y)
{
int res;
asm ("smlabb %0,%1,%2,%3;\n":"=&r" (res)
: "%r" (x), "r" (y), "r" (a));
return (res);
}
#undef MULT16_32_Q15
static inline spx_word32_t
MULT16_32_Q15 (spx_word16_t x, spx_word32_t y)
{
int res;
asm ("smulwb %0,%1,%2;\n":"=&r" (res)
: "%r" (y << 1), "r" (x));
return (res);
}
#undef MAC16_32_Q15
static inline spx_word32_t
MAC16_32_Q15 (spx_word32_t a, spx_word16_t x, spx_word32_t y)
{
int res;
asm ("smlawb %0,%1,%2,%3;\n":"=&r" (res)
: "%r" (y << 1), "r" (x), "r" (a));
return (res);
}
#undef MULT16_32_Q11
static inline spx_word32_t
MULT16_32_Q11 (spx_word16_t x, spx_word32_t y)
{
int res;
asm ("smulwb %0,%1,%2;\n":"=&r" (res)
: "%r" (y << 5), "r" (x));
return (res);
}
#undef MAC16_32_Q11
static inline spx_word32_t
MAC16_32_Q11 (spx_word32_t a, spx_word16_t x, spx_word32_t y)
{
int res;
asm ("smlawb %0,%1,%2,%3;\n":"=&r" (res)
: "%r" (y << 5), "r" (x), "r" (a));
return (res);
}
#undef DIV32_16
static inline short
DIV32_16 (int a, int b)
{
int res = 0;
int dead1, dead2, dead3, dead4, dead5;
__asm__ __volatile__ ("\teor %5, %0, %1\n"
"\tmovs %4, %0\n"
"\trsbmi %0, %0, #0 \n"
"\tmovs %4, %1\n"
"\trsbmi %1, %1, #0 \n"
"\tmov %4, #1\n"
"\tsubs %3, %0, %1, asl #14 \n"
"\torrpl %2, %2, %4, asl #14 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1, asl #13 \n"
"\torrpl %2, %2, %4, asl #13 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1, asl #12 \n"
"\torrpl %2, %2, %4, asl #12 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1, asl #11 \n"
"\torrpl %2, %2, %4, asl #11 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1, asl #10 \n"
"\torrpl %2, %2, %4, asl #10 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1, asl #9 \n"
"\torrpl %2, %2, %4, asl #9 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1, asl #8 \n"
"\torrpl %2, %2, %4, asl #8 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1, asl #7 \n"
"\torrpl %2, %2, %4, asl #7 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1, asl #6 \n"
"\torrpl %2, %2, %4, asl #6 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1, asl #5 \n"
"\torrpl %2, %2, %4, asl #5 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1, asl #4 \n"
"\torrpl %2, %2, %4, asl #4 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1, asl #3 \n"
"\torrpl %2, %2, %4, asl #3 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1, asl #2 \n"
"\torrpl %2, %2, %4, asl #2 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1, asl #1 \n"
"\torrpl %2, %2, %4, asl #1 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1 \n"
"\torrpl %2, %2, %4 \n"
"\tmovpl %0, %3 \n"
"\tmovs %5, %5, lsr #31 \n"
"\trsbne %2, %2, #0 \n":"=r" (dead1), "=r" (dead2), "=r" (res),
"=r" (dead3), "=r" (dead4), "=r" (dead5)
:"0" (a), "1" (b), "2" (res)
:"memory", "cc");
return res;
}
#endif

View file

@ -1,134 +0,0 @@
/* Copyright (C) 2005 Analog Devices
Author: Jean-Marc Valin */
/**
@file fixed_bfin.h
@brief Blackfin fixed-point operations
*/
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of the Xiph.org Foundation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef FIXED_BFIN_H
#define FIXED_BFIN_H
#undef PDIV32_16
static inline spx_word16_t
PDIV32_16 (spx_word32_t a, spx_word16_t b)
{
spx_word32_t res, bb;
bb = b;
a += b >> 1;
__asm__ ("P0 = 15;\n\t" "R0 = %1;\n\t" "R1 = %2;\n\t"
//"R0 = R0 + R1;\n\t"
"R0 <<= 1;\n\t" "DIVS (R0, R1);\n\t" "LOOP divide%= LC0 = P0;\n\t" "LOOP_BEGIN divide%=;\n\t" "DIVQ (R0, R1);\n\t" "LOOP_END divide%=;\n\t" "R0 = R0.L;\n\t" "%0 = R0;\n\t":"=m"
(res)
: "m" (a), "m" (bb)
: "P0", "R0", "R1", "cc");
return res;
}
#undef DIV32_16
static inline spx_word16_t
DIV32_16 (spx_word32_t a, spx_word16_t b)
{
spx_word32_t res, bb;
bb = b;
/* Make the roundinf consistent with the C version
(do we need to do that?) */
if (a < 0)
a += (b - 1);
__asm__ ("P0 = 15;\n\t" "R0 = %1;\n\t" "R1 = %2;\n\t" "R0 <<= 1;\n\t" "DIVS (R0, R1);\n\t" "LOOP divide%= LC0 = P0;\n\t" "LOOP_BEGIN divide%=;\n\t" "DIVQ (R0, R1);\n\t" "LOOP_END divide%=;\n\t" "R0 = R0.L;\n\t" "%0 = R0;\n\t":"=m" (res)
: "m" (a), "m" (bb)
: "P0", "R0", "R1", "cc");
return res;
}
#undef MAX16
static inline spx_word16_t
MAX16 (spx_word16_t a, spx_word16_t b)
{
spx_word32_t res;
__asm__ ("%1 = %1.L (X);\n\t" "%2 = %2.L (X);\n\t" "%0 = MAX(%1,%2);":"=d" (res)
: "%d" (a), "d" (b)
);
return res;
}
#undef MULT16_32_Q15
static inline spx_word32_t
MULT16_32_Q15 (spx_word16_t a, spx_word32_t b)
{
spx_word32_t res;
__asm__ ("A1 = %2.L*%1.L (M);\n\t" "A1 = A1 >>> 15;\n\t" "%0 = (A1 += %2.L*%1.H) ;\n\t":"=&W" (res),
"=&d"
(b)
: "d" (a), "1" (b)
: "A1");
return res;
}
#undef MAC16_32_Q15
static inline spx_word32_t
MAC16_32_Q15 (spx_word32_t c, spx_word16_t a, spx_word32_t b)
{
spx_word32_t res;
__asm__ ("A1 = %2.L*%1.L (M);\n\t" "A1 = A1 >>> 15;\n\t" "%0 = (A1 += %2.L*%1.H);\n\t" "%0 = %0 + %4;\n\t":"=&W" (res),
"=&d"
(b)
: "d" (a), "1" (b), "d" (c)
: "A1");
return res;
}
#undef MULT16_32_Q14
static inline spx_word32_t
MULT16_32_Q14 (spx_word16_t a, spx_word32_t b)
{
spx_word32_t res;
__asm__ ("%2 <<= 1;\n\t" "A1 = %1.L*%2.L (M);\n\t" "A1 = A1 >>> 15;\n\t" "%0 = (A1 += %1.L*%2.H);\n\t":"=W" (res), "=d" (a),
"=d"
(b)
: "1" (a), "2" (b)
: "A1");
return res;
}
#undef MAC16_32_Q14
static inline spx_word32_t
MAC16_32_Q14 (spx_word32_t c, spx_word16_t a, spx_word32_t b)
{
spx_word32_t res;
__asm__ ("%1 <<= 1;\n\t" "A1 = %2.L*%1.L (M);\n\t" "A1 = A1 >>> 15;\n\t" "%0 = (A1 += %2.L*%1.H);\n\t" "%0 = %0 + %4;\n\t":"=&W" (res),
"=&d"
(b)
: "d" (a), "1" (b), "d" (c)
: "A1");
return res;
}
#endif

View file

@ -1,525 +0,0 @@
/* Copyright (C) 2003 Jean-Marc Valin */
/**
@file fixed_debug.h
@brief Fixed-point operations with debugging
*/
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of the Xiph.org Foundation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef FIXED_DEBUG_H
#define FIXED_DEBUG_H
#include <stdio.h>
extern long long spx_mips;
#define MIPS_INC spx_mips++,
#define QCONST16(x,bits) ((spx_word16_t)(.5+(x)*(((spx_word32_t)1)<<(bits))))
#define QCONST32(x,bits) ((spx_word32_t)(.5+(x)*(((spx_word32_t)1)<<(bits))))
#define VERIFY_SHORT(x) ((x)<=32767&&(x)>=-32768)
#define VERIFY_INT(x) ((x)<=2147483647LL&&(x)>=-2147483648LL)
static inline short
NEG16 (int x)
{
int res;
if (!VERIFY_SHORT (x)) {
fprintf (stderr, "NEG16: input is not short: %d\n", (int) x);
}
res = -x;
if (!VERIFY_SHORT (res))
fprintf (stderr, "NEG16: output is not short: %d\n", (int) res);
spx_mips++;
return res;
}
static inline int
NEG32 (long long x)
{
long long res;
if (!VERIFY_INT (x)) {
fprintf (stderr, "NEG16: input is not int: %d\n", (int) x);
}
res = -x;
if (!VERIFY_INT (res))
fprintf (stderr, "NEG16: output is not int: %d\n", (int) res);
spx_mips++;
return res;
}
#define EXTRACT16(x) _EXTRACT16(x, __FILE__, __LINE__)
static inline short
_EXTRACT16 (int x, char *file, int line)
{
int res;
if (!VERIFY_SHORT (x)) {
fprintf (stderr, "EXTRACT16: input is not short: %d in %s: line %d\n", x,
file, line);
}
res = x;
spx_mips++;
return res;
}
#define EXTEND32(x) _EXTEND32(x, __FILE__, __LINE__)
static inline int
_EXTEND32 (int x, char *file, int line)
{
int res;
if (!VERIFY_SHORT (x)) {
fprintf (stderr, "EXTEND32: input is not short: %d in %s: line %d\n", x,
file, line);
}
res = x;
spx_mips++;
return res;
}
#define SHR16(a, shift) _SHR16(a, shift, __FILE__, __LINE__)
static inline short
_SHR16 (int a, int shift, char *file, int line)
{
int res;
if (!VERIFY_SHORT (a) || !VERIFY_SHORT (shift)) {
fprintf (stderr, "SHR16: inputs are not short: %d >> %d in %s: line %d\n",
a, shift, file, line);
}
res = a >> shift;
if (!VERIFY_SHORT (res))
fprintf (stderr, "SHR16: output is not short: %d in %s: line %d\n", res,
file, line);
spx_mips++;
return res;
}
#define SHL16(a, shift) _SHL16(a, shift, __FILE__, __LINE__)
static inline short
_SHL16 (int a, int shift, char *file, int line)
{
int res;
if (!VERIFY_SHORT (a) || !VERIFY_SHORT (shift)) {
fprintf (stderr, "SHL16: inputs are not short: %d %d in %s: line %d\n", a,
shift, file, line);
}
res = a << shift;
if (!VERIFY_SHORT (res))
fprintf (stderr, "SHL16: output is not short: %d in %s: line %d\n", res,
file, line);
spx_mips++;
return res;
}
static inline int
SHR32 (long long a, int shift)
{
long long res;
if (!VERIFY_INT (a) || !VERIFY_SHORT (shift)) {
fprintf (stderr, "SHR32: inputs are not int: %d %d\n", (int) a, shift);
}
res = a >> shift;
if (!VERIFY_INT (res)) {
fprintf (stderr, "SHR32: output is not int: %d\n", (int) res);
}
spx_mips++;
return res;
}
static inline int
SHL32 (long long a, int shift)
{
long long res;
if (!VERIFY_INT (a) || !VERIFY_SHORT (shift)) {
fprintf (stderr, "SHL32: inputs are not int: %d %d\n", (int) a, shift);
}
res = a << shift;
if (!VERIFY_INT (res)) {
fprintf (stderr, "SHL32: output is not int: %d\n", (int) res);
}
spx_mips++;
return res;
}
#define PSHR16(a,shift) (SHR16(ADD16((a),((1<<((shift))>>1))),shift))
#define PSHR32(a,shift) (SHR32(ADD32((a),((EXTEND32(1)<<((shift))>>1))),shift))
#define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift)))
#define SATURATE16(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
#define SATURATE32(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
//#define SHR(a,shift) ((a) >> (shift))
//#define SHL(a,shift) ((a) << (shift))
#define ADD16(a, b) _ADD16(a, b, __FILE__, __LINE__)
static inline short
_ADD16 (int a, int b, char *file, int line)
{
int res;
if (!VERIFY_SHORT (a) || !VERIFY_SHORT (b)) {
fprintf (stderr, "ADD16: inputs are not short: %d %d in %s: line %d\n", a,
b, file, line);
}
res = a + b;
if (!VERIFY_SHORT (res)) {
fprintf (stderr, "ADD16: output is not short: %d+%d=%d in %s: line %d\n", a,
b, res, file, line);
}
spx_mips++;
return res;
}
#define SUB16(a, b) _SUB16(a, b, __FILE__, __LINE__)
static inline short
_SUB16 (int a, int b, char *file, int line)
{
int res;
if (!VERIFY_SHORT (a) || !VERIFY_SHORT (b)) {
fprintf (stderr, "SUB16: inputs are not short: %d %d in %s: line %d\n", a,
b, file, line);
}
res = a - b;
if (!VERIFY_SHORT (res))
fprintf (stderr, "SUB16: output is not short: %d in %s: line %d\n", res,
file, line);
spx_mips++;
return res;
}
#define ADD32(a, b) _ADD32(a, b, __FILE__, __LINE__)
static inline int
_ADD32 (long long a, long long b, char *file, int line)
{
long long res;
if (!VERIFY_INT (a) || !VERIFY_INT (b)) {
fprintf (stderr, "ADD32: inputs are not int: %d %d in %s: line %d\n",
(int) a, (int) b, file, line);
}
res = a + b;
if (!VERIFY_INT (res)) {
fprintf (stderr, "ADD32: output is not int: %d in %s: line %d\n", (int) res,
file, line);
}
spx_mips++;
return res;
}
static inline int
SUB32 (long long a, long long b)
{
long long res;
if (!VERIFY_INT (a) || !VERIFY_INT (b)) {
fprintf (stderr, "SUB32: inputs are not int: %d %d\n", (int) a, (int) b);
}
res = a - b;
if (!VERIFY_INT (res))
fprintf (stderr, "SUB32: output is not int: %d\n", (int) res);
spx_mips++;
return res;
}
#define ADD64(a,b) (MIPS_INC(a)+(b))
/* result fits in 16 bits */
static inline short
MULT16_16_16 (int a, int b)
{
int res;
if (!VERIFY_SHORT (a) || !VERIFY_SHORT (b)) {
fprintf (stderr, "MULT16_16_16: inputs are not short: %d %d\n", a, b);
}
res = a * b;
if (!VERIFY_SHORT (res))
fprintf (stderr, "MULT16_16_16: output is not short: %d\n", res);
spx_mips++;
return res;
}
#define MULT16_16(a, b) _MULT16_16(a, b, __FILE__, __LINE__)
static inline int
_MULT16_16 (int a, int b, char *file, int line)
{
long long res;
if (!VERIFY_SHORT (a) || !VERIFY_SHORT (b)) {
fprintf (stderr, "MULT16_16: inputs are not short: %d %d in %s: line %d\n",
a, b, file, line);
}
res = ((long long) a) * b;
if (!VERIFY_INT (res))
fprintf (stderr, "MULT16_16: output is not int: %d in %s: line %d\n",
(int) res, file, line);
spx_mips++;
return res;
}
#define MAC16_16(c,a,b) (spx_mips--,ADD32((c),MULT16_16((a),(b))))
#define MAC16_16_Q11(c,a,b) (EXTRACT16(ADD16((c),EXTRACT16(SHR32(MULT16_16((a),(b)),11)))))
#define MAC16_16_Q13(c,a,b) (EXTRACT16(ADD16((c),EXTRACT16(SHR32(MULT16_16((a),(b)),13)))))
#define MAC16_16_P13(c,a,b) (EXTRACT16(ADD32((c),SHR32(ADD32(4096,MULT16_16((a),(b))),13))))
#define MULT16_32_QX(a, b, Q) _MULT16_32_QX(a, b, Q, __FILE__, __LINE__)
static inline int
_MULT16_32_QX (int a, long long b, int Q, char *file, int line)
{
long long res;
if (!VERIFY_SHORT (a) || !VERIFY_INT (b)) {
fprintf (stderr,
"MULT16_32_Q%d: inputs are not short+int: %d %d in %s: line %d\n", Q,
(int) a, (int) b, file, line);
}
if (ABS32 (b) >= (EXTEND32 (1) << (15 + Q)))
fprintf (stderr,
"MULT16_32_Q%d: second operand too large: %d %d in %s: line %d\n", Q,
(int) a, (int) b, file, line);
res = (((long long) a) * (long long) b) >> Q;
if (!VERIFY_INT (res))
fprintf (stderr,
"MULT16_32_Q%d: output is not int: %d*%d=%d in %s: line %d\n", Q,
(int) a, (int) b, (int) res, file, line);
spx_mips += 5;
return res;
}
static inline int
MULT16_32_PX (int a, long long b, int Q)
{
long long res;
if (!VERIFY_SHORT (a) || !VERIFY_INT (b)) {
fprintf (stderr, "MULT16_32_P%d: inputs are not short+int: %d %d\n", Q,
(int) a, (int) b);
}
if (ABS32 (b) >= (EXTEND32 (1) << (15 + Q)))
fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d\n", Q,
(int) a, (int) b);
res = ((((long long) a) * (long long) b) + ((EXTEND32 (1) << Q) >> 1)) >> Q;
if (!VERIFY_INT (res))
fprintf (stderr, "MULT16_32_P%d: output is not int: %d*%d=%d\n", Q, (int) a,
(int) b, (int) res);
spx_mips += 5;
return res;
}
#define MULT16_32_Q11(a,b) MULT16_32_QX(a,b,11)
#define MAC16_32_Q11(c,a,b) ADD32((c),MULT16_32_Q11((a),(b)))
#define MULT16_32_Q12(a,b) MULT16_32_QX(a,b,12)
#define MULT16_32_Q13(a,b) MULT16_32_QX(a,b,13)
#define MULT16_32_Q14(a,b) MULT16_32_QX(a,b,14)
#define MULT16_32_Q15(a,b) MULT16_32_QX(a,b,15)
#define MULT16_32_P15(a,b) MULT16_32_PX(a,b,15)
#define MAC16_32_Q15(c,a,b) ADD32((c),MULT16_32_Q15((a),(b)))
static inline int
SATURATE (int a, int b)
{
if (a > b)
a = b;
if (a < -b)
a = -b;
return a;
}
static inline int
MULT16_16_Q11_32 (int a, int b)
{
long long res;
if (!VERIFY_SHORT (a) || !VERIFY_SHORT (b)) {
fprintf (stderr, "MULT16_16_Q11: inputs are not short: %d %d\n", a, b);
}
res = ((long long) a) * b;
res >>= 11;
if (!VERIFY_INT (res))
fprintf (stderr, "MULT16_16_Q11: output is not short: %d*%d=%d\n", (int) a,
(int) b, (int) res);
spx_mips += 3;
return res;
}
static inline short
MULT16_16_Q13 (int a, int b)
{
long long res;
if (!VERIFY_SHORT (a) || !VERIFY_SHORT (b)) {
fprintf (stderr, "MULT16_16_Q13: inputs are not short: %d %d\n", a, b);
}
res = ((long long) a) * b;
res >>= 13;
if (!VERIFY_SHORT (res))
fprintf (stderr, "MULT16_16_Q13: output is not short: %d*%d=%d\n", a, b,
(int) res);
spx_mips += 3;
return res;
}
static inline short
MULT16_16_Q14 (int a, int b)
{
long long res;
if (!VERIFY_SHORT (a) || !VERIFY_SHORT (b)) {
fprintf (stderr, "MULT16_16_Q14: inputs are not short: %d %d\n", a, b);
}
res = ((long long) a) * b;
res >>= 14;
if (!VERIFY_SHORT (res))
fprintf (stderr, "MULT16_16_Q14: output is not short: %d\n", (int) res);
spx_mips += 3;
return res;
}
static inline short
MULT16_16_Q15 (int a, int b)
{
long long res;
if (!VERIFY_SHORT (a) || !VERIFY_SHORT (b)) {
fprintf (stderr, "MULT16_16_Q15: inputs are not short: %d %d\n", a, b);
}
res = ((long long) a) * b;
res >>= 15;
if (!VERIFY_SHORT (res)) {
fprintf (stderr, "MULT16_16_Q15: output is not short: %d\n", (int) res);
}
spx_mips += 3;
return res;
}
static inline short
MULT16_16_P13 (int a, int b)
{
long long res;
if (!VERIFY_SHORT (a) || !VERIFY_SHORT (b)) {
fprintf (stderr, "MULT16_16_P13: inputs are not short: %d %d\n", a, b);
}
res = ((long long) a) * b;
res += 4096;
if (!VERIFY_INT (res))
fprintf (stderr, "MULT16_16_P13: overflow: %d*%d=%d\n", a, b, (int) res);
res >>= 13;
if (!VERIFY_SHORT (res))
fprintf (stderr, "MULT16_16_P13: output is not short: %d*%d=%d\n", a, b,
(int) res);
spx_mips += 4;
return res;
}
static inline short
MULT16_16_P14 (int a, int b)
{
long long res;
if (!VERIFY_SHORT (a) || !VERIFY_SHORT (b)) {
fprintf (stderr, "MULT16_16_P14: inputs are not short: %d %d\n", a, b);
}
res = ((long long) a) * b;
res += 8192;
if (!VERIFY_INT (res))
fprintf (stderr, "MULT16_16_P14: overflow: %d*%d=%d\n", a, b, (int) res);
res >>= 14;
if (!VERIFY_SHORT (res))
fprintf (stderr, "MULT16_16_P14: output is not short: %d*%d=%d\n", a, b,
(int) res);
spx_mips += 4;
return res;
}
static inline short
MULT16_16_P15 (int a, int b)
{
long long res;
if (!VERIFY_SHORT (a) || !VERIFY_SHORT (b)) {
fprintf (stderr, "MULT16_16_P15: inputs are not short: %d %d\n", a, b);
}
res = ((long long) a) * b;
res += 16384;
if (!VERIFY_INT (res))
fprintf (stderr, "MULT16_16_P15: overflow: %d*%d=%d\n", a, b, (int) res);
res >>= 15;
if (!VERIFY_SHORT (res))
fprintf (stderr, "MULT16_16_P15: output is not short: %d*%d=%d\n", a, b,
(int) res);
spx_mips += 4;
return res;
}
#define DIV32_16(a, b) _DIV32_16(a, b, __FILE__, __LINE__)
static inline int
_DIV32_16 (long long a, long long b, char *file, int line)
{
long long res;
if (b == 0) {
fprintf (stderr, "DIV32_16: divide by zero: %d/%d in %s: line %d\n",
(int) a, (int) b, file, line);
return 0;
}
if (!VERIFY_INT (a) || !VERIFY_SHORT (b)) {
fprintf (stderr,
"DIV32_16: inputs are not int/short: %d %d in %s: line %d\n", (int) a,
(int) b, file, line);
}
res = a / b;
if (!VERIFY_SHORT (res)) {
fprintf (stderr,
"DIV32_16: output is not short: %d / %d = %d in %s: line %d\n", (int) a,
(int) b, (int) res, file, line);
if (res > 32767)
res = 32767;
if (res < -32768)
res = -32768;
}
spx_mips += 20;
return res;
}
#define DIV32(a, b) _DIV32(a, b, __FILE__, __LINE__)
static inline int
_DIV32 (long long a, long long b, char *file, int line)
{
long long res;
if (b == 0) {
fprintf (stderr, "DIV32: divide by zero: %d/%d in %s: line %d\n", (int) a,
(int) b, file, line);
return 0;
}
if (!VERIFY_INT (a) || !VERIFY_INT (b)) {
fprintf (stderr, "DIV32: inputs are not int/short: %d %d in %s: line %d\n",
(int) a, (int) b, file, line);
}
res = a / b;
if (!VERIFY_INT (res))
fprintf (stderr, "DIV32: output is not int: %d in %s: line %d\n", (int) res,
file, line);
spx_mips += 36;
return res;
}
#define PDIV32(a,b) DIV32(ADD32((a),(b)>>1),b)
#define PDIV32_16(a,b) DIV32_16(ADD32((a),(b)>>1),b)
#endif

View file

@ -47,14 +47,14 @@
#define SHR32(a,shift) ((a) >> (shift))
#define SHL32(a,shift) ((a) << (shift))
#define PSHR16(a,shift) (SHR16((a)+((1<<((shift))>>1)),shift))
#define PSHR32(a,shift) (SHR32((a)+((EXTEND32(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)+((EXTEND32(1)<<((shift))>>1)),shift))
#define PSHR(a,shift) (SHR((a)+((1<<((shift))>>1)),shift))
#define SATURATE(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
/* GStreamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
* Copyright (C) <2007-2008> Sebastian Dröge <sebastian.droege@collabora.co.uk>
* Copyright (C) <2007> Sebastian Dröge <slomo@circular-chaos.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@ -24,7 +24,6 @@
#include <gst/gst.h>
#include <gst/base/gstbasetransform.h>
#include <gst/audio/audio.h>
#include "speex_resampler_wrapper.h"
@ -58,25 +57,18 @@ struct _GstSpeexResample {
gboolean need_discont;
guint64 next_offset;
guint64 offset;
guint64 ts_offset;
GstClockTime next_ts;
GstClockTime next_upstream_ts;
GstClockTime prev_ts, prev_duration;
gint channels;
gint inrate;
gint outrate;
gint quality;
gint width;
gboolean fp;
guint8 *tmp_in;
guint tmp_in_size;
guint8 *tmp_out;
guint tmp_out_size;
int channels;
int inrate;
int outrate;
int quality;
SpeexResamplerState *state;
const SpeexResampleFuncs *funcs;
};
struct _GstSpeexResampleClass {

File diff suppressed because it is too large Load diff

View file

@ -1,128 +0,0 @@
/* Copyright (C) 2007-2008 Jean-Marc Valin
* Copyright (C) 2008 Thorvald Natvig
*/
/**
@file resample_sse.h
@brief Resampler functions (SSE version)
*/
/*
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.
*/
#include <xmmintrin.h>
#define OVERRIDE_INNER_PRODUCT_SINGLE
static inline float inner_product_single(const float *a, const float *b, unsigned int len)
{
int i;
float ret;
__m128 sum = _mm_setzero_ps();
for (i=0;i<len;i+=8)
{
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_loadu_ps(a+i), _mm_loadu_ps(b+i)));
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_loadu_ps(a+i+4), _mm_loadu_ps(b+i+4)));
}
sum = _mm_add_ps(sum, _mm_movehl_ps(sum, sum));
sum = _mm_add_ss(sum, _mm_shuffle_ps(sum, sum, 0x55));
_mm_store_ss(&ret, sum);
return ret;
}
#define OVERRIDE_INTERPOLATE_PRODUCT_SINGLE
static inline float interpolate_product_single(const float *a, const float *b, unsigned int len, const spx_uint32_t oversample, float *frac) {
int i;
float ret;
__m128 sum = _mm_setzero_ps();
__m128 f = _mm_loadu_ps(frac);
for(i=0;i<len;i+=2)
{
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_load1_ps(a+i), _mm_loadu_ps(b+i*oversample)));
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_load1_ps(a+i+1), _mm_loadu_ps(b+(i+1)*oversample)));
}
sum = _mm_mul_ps(f, sum);
sum = _mm_add_ps(sum, _mm_movehl_ps(sum, sum));
sum = _mm_add_ss(sum, _mm_shuffle_ps(sum, sum, 0x55));
_mm_store_ss(&ret, sum);
return ret;
}
#ifdef _USE_SSE2
#include <emmintrin.h>
#define OVERRIDE_INNER_PRODUCT_DOUBLE
static inline double inner_product_double(const float *a, const float *b, unsigned int len)
{
int i;
double ret;
__m128d sum = _mm_setzero_pd();
__m128 t;
for (i=0;i<len;i+=8)
{
t = _mm_mul_ps(_mm_loadu_ps(a+i), _mm_loadu_ps(b+i));
sum = _mm_add_pd(sum, _mm_cvtps_pd(t));
sum = _mm_add_pd(sum, _mm_cvtps_pd(_mm_movehl_ps(t, t)));
t = _mm_mul_ps(_mm_loadu_ps(a+i+4), _mm_loadu_ps(b+i+4));
sum = _mm_add_pd(sum, _mm_cvtps_pd(t));
sum = _mm_add_pd(sum, _mm_cvtps_pd(_mm_movehl_ps(t, t)));
}
sum = _mm_add_sd(sum, (__m128d) _mm_movehl_ps((__m128) sum, (__m128) sum));
_mm_store_sd(&ret, sum);
return ret;
}
#define OVERRIDE_INTERPOLATE_PRODUCT_DOUBLE
static inline double interpolate_product_double(const float *a, const float *b, unsigned int len, const spx_uint32_t oversample, float *frac) {
int i;
double ret;
__m128d sum;
__m128d sum1 = _mm_setzero_pd();
__m128d sum2 = _mm_setzero_pd();
__m128 f = _mm_loadu_ps(frac);
__m128d f1 = _mm_cvtps_pd(f);
__m128d f2 = _mm_cvtps_pd(_mm_movehl_ps(f,f));
__m128 t;
for(i=0;i<len;i+=2)
{
t = _mm_mul_ps(_mm_load1_ps(a+i), _mm_loadu_ps(b+i*oversample));
sum1 = _mm_add_pd(sum1, _mm_cvtps_pd(t));
sum2 = _mm_add_pd(sum2, _mm_cvtps_pd(_mm_movehl_ps(t, t)));
t = _mm_mul_ps(_mm_load1_ps(a+i+1), _mm_loadu_ps(b+(i+1)*oversample));
sum1 = _mm_add_pd(sum1, _mm_cvtps_pd(t));
sum2 = _mm_add_pd(sum2, _mm_cvtps_pd(_mm_movehl_ps(t, t)));
}
sum1 = _mm_mul_pd(f1, sum1);
sum2 = _mm_mul_pd(f2, sum2);
sum = _mm_add_pd(sum1, sum2);
sum = _mm_add_sd(sum, (__m128d) _mm_movehl_ps((__m128) sum, (__m128) sum));
_mm_store_sd(&ret, sum);
return ret;
}
#endif

View file

@ -41,6 +41,8 @@
#ifdef OUTSIDE_SPEEX
#include <glib.h>
/********* WARNING: MENTAL SANITY ENDS HERE *************/
/* If the resampler is defined outside of Speex, we change the symbol names so that
@ -53,7 +55,7 @@
#define CAT_PREFIX2(a,b) a ## b
#define CAT_PREFIX(a,b) CAT_PREFIX2(a, b)
#define speex_resampler_init CAT_PREFIX(RANDOM_PREFIX,_resampler_init)
#define speex_resampler_init_frac CAT_PREFIX(RANDOM_PREFIX,_resampler_init_frac)
#define speex_resampler_destroy CAT_PREFIX(RANDOM_PREFIX,_resampler_destroy)
@ -81,20 +83,15 @@
#define spx_int32_t gint32
#define spx_uint16_t guint16
#define spx_uint32_t guint32
#else /* OUTSIDE_SPEEX */
#ifdef _BUILD_SPEEX
# include "speex_types.h"
#else
# include <speex/speex_types.h>
#endif
#include "speex/speex_types.h"
#endif /* OUTSIDE_SPEEX */
#ifdef __cplusplus
extern "C"
{
extern "C" {
#endif
#define SPEEX_RESAMPLER_QUALITY_MAX 10
@ -103,19 +100,18 @@ extern "C"
#define SPEEX_RESAMPLER_QUALITY_VOIP 3
#define SPEEX_RESAMPLER_QUALITY_DESKTOP 5
enum
{
RESAMPLER_ERR_SUCCESS = 0,
RESAMPLER_ERR_ALLOC_FAILED = 1,
RESAMPLER_ERR_BAD_STATE = 2,
RESAMPLER_ERR_INVALID_ARG = 3,
RESAMPLER_ERR_PTR_OVERLAP = 4,
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
};
RESAMPLER_ERR_MAX_ERROR
};
struct SpeexResamplerState_;
typedef struct SpeexResamplerState_ SpeexResamplerState;
struct SpeexResamplerState_;
typedef struct SpeexResamplerState_ SpeexResamplerState;
/** Create a new resampler with integer input and output rates.
* @param nb_channels Number of channels to be processed
@ -126,8 +122,11 @@ extern "C"
* @return Newly created resampler state
* @retval NULL Error: not enough memory
*/
SpeexResamplerState *speex_resampler_init (spx_uint32_t nb_channels,
spx_uint32_t in_rate, spx_uint32_t out_rate, int quality, int *err);
SpeexResamplerState *speex_resampler_init(spx_uint32_t nb_channels,
spx_uint32_t in_rate,
spx_uint32_t out_rate,
int quality,
int *err);
/** Create a new resampler with fractional input/output rates. The sampling
* rate ratio is an arbitrary rational number with both the numerator and
@ -142,15 +141,18 @@ extern "C"
* @return Newly created resampler state
* @retval NULL Error: not enough memory
*/
SpeexResamplerState *speex_resampler_init_frac (spx_uint32_t nb_channels,
spx_uint32_t ratio_num,
spx_uint32_t ratio_den,
spx_uint32_t in_rate, spx_uint32_t out_rate, int quality, int *err);
SpeexResamplerState *speex_resampler_init_frac(spx_uint32_t nb_channels,
spx_uint32_t ratio_num,
spx_uint32_t ratio_den,
spx_uint32_t in_rate,
spx_uint32_t out_rate,
int quality,
int *err);
/** Destroy a resampler state.
* @param st Resampler state
*/
void speex_resampler_destroy (SpeexResamplerState * st);
void speex_resampler_destroy(SpeexResamplerState *st);
/** Resample a float array. The input and output buffers must *not* overlap.
* @param st Resampler state
@ -162,17 +164,12 @@ extern "C"
* @param out Output buffer
* @param out_len Size of the output buffer. Returns the number of samples written
*/
#ifdef DOUBLE_PRECISION
int speex_resampler_process_float (SpeexResamplerState * st,
spx_uint32_t channel_index,
const double *in,
spx_uint32_t * in_len, double *out, spx_uint32_t * 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);
#endif
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
@ -184,10 +181,12 @@ extern "C"
* @param out Output buffer
* @param out_len Size of the output buffer. Returns the number of samples written
*/
int speex_resampler_process_int (SpeexResamplerState * st,
spx_uint32_t channel_index,
const spx_int16_t * in,
spx_uint32_t * in_len, spx_int16_t * out, spx_uint32_t * out_len);
int speex_resampler_process_int(SpeexResamplerState *st,
spx_uint32_t channel_index,
const spx_int16_t *in,
spx_uint32_t *in_len,
spx_int16_t *out,
spx_uint32_t *out_len);
/** Resample an interleaved float array. The input and output buffers must *not* overlap.
* @param st Resampler state
@ -198,15 +197,11 @@ extern "C"
* @param out_len Size of the output buffer. Returns the number of samples written.
* This is all per-channel.
*/
#ifdef DOUBLE_PRECISION
int speex_resampler_process_interleaved_float (SpeexResamplerState * st,
const double *in,
spx_uint32_t * in_len, double *out, spx_uint32_t * out_len);
#else
int speex_resampler_process_interleaved_float (SpeexResamplerState * st,
const float *in,
spx_uint32_t * in_len, float *out, spx_uint32_t * out_len);
#endif
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
@ -217,25 +212,29 @@ extern "C"
* @param out_len Size of the output buffer. Returns the number of samples written.
* This is all per-channel.
*/
int speex_resampler_process_interleaved_int (SpeexResamplerState * st,
const spx_int16_t * in,
spx_uint32_t * in_len, spx_int16_t * out, spx_uint32_t * out_len);
int speex_resampler_process_interleaved_int(SpeexResamplerState *st,
const spx_int16_t *in,
spx_uint32_t *in_len,
spx_int16_t *out,
spx_uint32_t *out_len);
/** Set (change) the input/output sampling rates (integer value).
* @param st Resampler state
* @param in_rate Input sampling rate (integer number of Hz).
* @param out_rate Output sampling rate (integer number of Hz).
*/
int speex_resampler_set_rate (SpeexResamplerState * st,
spx_uint32_t in_rate, spx_uint32_t out_rate);
int speex_resampler_set_rate(SpeexResamplerState *st,
spx_uint32_t in_rate,
spx_uint32_t out_rate);
/** Get the current input/output sampling rates (integer value).
* @param st Resampler state
* @param in_rate Input sampling rate (integer number of Hz) copied.
* @param out_rate Output sampling rate (integer number of Hz) copied.
*/
void speex_resampler_get_rate (SpeexResamplerState * st,
spx_uint32_t * in_rate, spx_uint32_t * out_rate);
void speex_resampler_get_rate(SpeexResamplerState *st,
spx_uint32_t *in_rate,
spx_uint32_t *out_rate);
/** Set (change) the input/output sampling rates and resampling ratio
* (fractional values in Hz supported).
@ -245,9 +244,11 @@ extern "C"
* @param in_rate Input sampling rate rounded to the nearest integer (in Hz).
* @param out_rate Output sampling rate rounded to the nearest integer (in Hz).
*/
int speex_resampler_set_rate_frac (SpeexResamplerState * st,
spx_uint32_t ratio_num,
spx_uint32_t ratio_den, spx_uint32_t in_rate, spx_uint32_t out_rate);
int speex_resampler_set_rate_frac(SpeexResamplerState *st,
spx_uint32_t ratio_num,
spx_uint32_t ratio_den,
spx_uint32_t in_rate,
spx_uint32_t out_rate);
/** Get the current resampling ratio. This will be reduced to the least
* common denominator.
@ -255,60 +256,63 @@ extern "C"
* @param ratio_num Numerator of the sampling rate ratio copied
* @param ratio_den Denominator of the sampling rate ratio copied
*/
void speex_resampler_get_ratio (SpeexResamplerState * st,
spx_uint32_t * ratio_num, spx_uint32_t * ratio_den);
void speex_resampler_get_ratio(SpeexResamplerState *st,
spx_uint32_t *ratio_num,
spx_uint32_t *ratio_den);
/** Set (change) the conversion quality.
* @param st Resampler state
* @param quality Resampling quality between 0 and 10, where 0 has poor
* quality and 10 has very high quality.
*/
int speex_resampler_set_quality (SpeexResamplerState * st, int quality);
int speex_resampler_set_quality(SpeexResamplerState *st,
int quality);
/** Get the conversion quality.
* @param st Resampler state
* @param quality Resampling quality between 0 and 10, where 0 has poor
* quality and 10 has very high quality.
*/
void speex_resampler_get_quality (SpeexResamplerState * st, int *quality);
void speex_resampler_get_quality(SpeexResamplerState *st,
int *quality);
/** Set (change) the input stride.
* @param st Resampler state
* @param stride Input stride
*/
void speex_resampler_set_input_stride (SpeexResamplerState * st,
spx_uint32_t stride);
void speex_resampler_set_input_stride(SpeexResamplerState *st,
spx_uint32_t stride);
/** Get the input stride.
* @param st Resampler state
* @param stride Input stride copied
*/
void speex_resampler_get_input_stride (SpeexResamplerState * st,
spx_uint32_t * stride);
void speex_resampler_get_input_stride(SpeexResamplerState *st,
spx_uint32_t *stride);
/** Set (change) the output stride.
* @param st Resampler state
* @param stride Output stride
*/
void speex_resampler_set_output_stride (SpeexResamplerState * st,
spx_uint32_t stride);
void speex_resampler_set_output_stride(SpeexResamplerState *st,
spx_uint32_t stride);
/** Get the output stride.
* @param st Resampler state copied
* @param stride Output stride
*/
void speex_resampler_get_output_stride (SpeexResamplerState * st,
spx_uint32_t * stride);
void speex_resampler_get_output_stride(SpeexResamplerState *st,
spx_uint32_t *stride);
/** Get the latency in input samples introduced by the resampler.
* @param st Resampler state
*/
int speex_resampler_get_input_latency (SpeexResamplerState * st);
int speex_resampler_get_input_latency(SpeexResamplerState *st);
/** Get the latency in output samples introduced by the resampler.
* @param st Resampler state
*/
int speex_resampler_get_output_latency (SpeexResamplerState * st);
int speex_resampler_get_output_latency(SpeexResamplerState *st);
/** Make sure that the first samples to go out of the resamplers don't have
* leading zeros. This is only useful before starting to use a newly created
@ -318,18 +322,18 @@ extern "C"
* is the same for the first frame).
* @param st Resampler state
*/
int speex_resampler_skip_zeros (SpeexResamplerState * st);
int speex_resampler_skip_zeros(SpeexResamplerState *st);
/** Reset a resampler so a new (unrelated) stream can be processed.
* @param st Resampler state
*/
int speex_resampler_reset_mem (SpeexResamplerState * st);
int speex_resampler_reset_mem(SpeexResamplerState *st);
/** Returns the English meaning for an error code
* @param err Error code
* @return English string
*/
const char *speex_resampler_strerror (int err);
const char *speex_resampler_strerror(int err);
#ifdef __cplusplus
}

View file

@ -1,25 +0,0 @@
/* GStreamer
* Copyright (C) 2007-2008 Sebastian Dröge <sebastian.droege@collabora.co.uk>
*
* 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 DOUBLE_PRECISION
#define OUTSIDE_SPEEX
#define RANDOM_PREFIX resample_double
#include "resample.c"

View file

@ -1,5 +1,5 @@
/* GStreamer
* Copyright (C) 2007-2008 Sebastian Dröge <sebastian.droege@collabora.co.uk>
* Copyright (C) 2007 Sebastian Dröge <slomo@circular-chaos.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public

View file

@ -1,5 +1,5 @@
/* GStreamer
* Copyright (C) 2007-2008 Sebastian Dröge <sebastian.droege@collabora.co.uk>
* Copyright (C) 2007 Sebastian Dröge <slomo@circular-chaos.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public

View file

@ -1,5 +1,5 @@
/* GStreamer
* Copyright (C) 2007-2008 Sebastian Dröge <sebastian.droege@collabora.co.uk>
* Copyright (C) 2007 Sebastian Dröge <slomo@circular-chaos.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@ -39,123 +39,48 @@ enum
typedef struct SpeexResamplerState_ SpeexResamplerState;
typedef struct {
SpeexResamplerState *(*init) (guint32 nb_channels,
guint32 in_rate, guint32 out_rate, gint quality, gint * err);
void (*destroy) (SpeexResamplerState * st);
int (*process) (SpeexResamplerState *
st, const guint8 * in, guint32 * in_len, guint8 * out, guint32 * out_len);
int (*set_rate) (SpeexResamplerState * st,
guint32 in_rate, guint32 out_rate);
void (*get_rate) (SpeexResamplerState * st,
guint32 * in_rate, guint32 * out_rate);
void (*get_ratio) (SpeexResamplerState * st,
guint32 * ratio_num, guint32 * ratio_den);
int (*get_input_latency) (SpeexResamplerState * st);
int (*set_quality) (SpeexResamplerState * st, gint quality);
int (*reset_mem) (SpeexResamplerState * st);
int (*skip_zeros) (SpeexResamplerState * st);
const char * (*strerror) (gint err);
unsigned int width;
} SpeexResampleFuncs;
SpeexResamplerState *resample_float_resampler_init (guint32 nb_channels,
guint32 in_rate, guint32 out_rate, gint quality, gint * err);
void resample_float_resampler_destroy (SpeexResamplerState * st);
int resample_float_resampler_process_interleaved_float (SpeexResamplerState *
st, const guint8 * in, guint32 * in_len, guint8 * out, guint32 * out_len);
int resample_float_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_float_resampler_get_ratio (SpeexResamplerState * st,
guint32 * ratio_num, guint32 * ratio_den);
int resample_float_resampler_get_input_latency (SpeexResamplerState * st);
int resample_float_resampler_set_quality (SpeexResamplerState * st, gint quality);
int resample_float_resampler_reset_mem (SpeexResamplerState * st);
int resample_float_resampler_skip_zeros (SpeexResamplerState * st);
const char * resample_float_resampler_strerror (gint err);
static const SpeexResampleFuncs float_funcs =
{
resample_float_resampler_init,
resample_float_resampler_destroy,
resample_float_resampler_process_interleaved_float,
resample_float_resampler_set_rate,
resample_float_resampler_get_rate,
resample_float_resampler_get_ratio,
resample_float_resampler_get_input_latency,
resample_float_resampler_set_quality,
resample_float_resampler_reset_mem,
resample_float_resampler_skip_zeros,
resample_float_resampler_strerror,
32
};
SpeexResamplerState *resample_double_resampler_init (guint32 nb_channels,
guint32 in_rate, guint32 out_rate, gint quality, gint * err);
void resample_double_resampler_destroy (SpeexResamplerState * st);
int resample_double_resampler_process_interleaved_float (SpeexResamplerState *
st, const guint8 * in, guint32 * in_len, guint8 * out, guint32 * out_len);
int resample_double_resampler_set_rate (SpeexResamplerState * st,
guint32 in_rate, guint32 out_rate);
void resample_double_resampler_get_rate (SpeexResamplerState * st,
guint32 * in_rate, guint32 * out_rate);
void resample_double_resampler_get_ratio (SpeexResamplerState * st,
guint32 * ratio_num, guint32 * ratio_den);
int resample_double_resampler_get_input_latency (SpeexResamplerState * st);
int resample_double_resampler_set_quality (SpeexResamplerState * st, gint quality);
int resample_double_resampler_reset_mem (SpeexResamplerState * st);
int resample_double_resampler_skip_zeros (SpeexResamplerState * st);
const char * resample_double_resampler_strerror (gint err);
static const SpeexResampleFuncs double_funcs =
{
resample_double_resampler_init,
resample_double_resampler_destroy,
resample_double_resampler_process_interleaved_float,
resample_double_resampler_set_rate,
resample_double_resampler_get_rate,
resample_double_resampler_get_ratio,
resample_double_resampler_get_input_latency,
resample_double_resampler_set_quality,
resample_double_resampler_reset_mem,
resample_double_resampler_skip_zeros,
resample_double_resampler_strerror,
64
};
SpeexResamplerState *resample_int_resampler_init (guint32 nb_channels,
guint32 in_rate, guint32 out_rate, gint quality, gint * err);
void resample_int_resampler_destroy (SpeexResamplerState * st);
int resample_int_resampler_process_interleaved_int (SpeexResamplerState *
st, const guint8 * in, guint32 * in_len, guint8 * out, guint32 * out_len);
#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_int_resampler_get_input_latency (SpeexResamplerState * st);
int resample_int_resampler_set_quality (SpeexResamplerState * st, gint quality);
int resample_int_resampler_reset_mem (SpeexResamplerState * st);
int resample_int_resampler_skip_zeros (SpeexResamplerState * st);
const char * resample_int_resampler_strerror (gint err);
static const SpeexResampleFuncs int_funcs =
{
resample_int_resampler_init,
resample_int_resampler_destroy,
resample_int_resampler_process_interleaved_int,
resample_int_resampler_set_rate,
resample_int_resampler_get_rate,
resample_int_resampler_get_ratio,
resample_int_resampler_get_input_latency,
resample_int_resampler_set_quality,
resample_int_resampler_reset_mem,
resample_int_resampler_skip_zeros,
resample_int_resampler_strerror,
16
};
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__ */

View file

@ -1,700 +0,0 @@
/* GStreamer
*
* unit test for speexresample, based on the audioresample unit test
*
* Copyright (C) <2005> Thomas Vander Stichele <thomas at apestaart dot org>
* Copyright (C) <2006> Tim-Philipp Müller <tim at centricular net>
*
* 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.
*/
#include <unistd.h>
#include <gst/check/gstcheck.h>
#include <gst/audio/audio.h>
/* For ease of programming we use globals to keep refs for our floating
* src and sink pads we create; otherwise we always have to do get_pad,
* get_peer, and then remove references in every test function */
static GstPad *mysrcpad, *mysinkpad;
#define RESAMPLE_CAPS_FLOAT \
"audio/x-raw-float, " \
"channels = (int) [ 1, MAX ], " \
"rate = (int) [ 1, MAX ], " \
"endianness = (int) BYTE_ORDER, " \
"width = (int) { 32, 64 }"
#define RESAMPLE_CAPS_INT \
"audio/x-raw-int, " \
"channels = (int) [ 1, MAX ], " \
"rate = (int) [ 1, MAX ], " \
"endianness = (int) BYTE_ORDER, " \
"width = (int) 16, " \
"depth = (int) 16, " \
"signed = (bool) TRUE"
#define RESAMPLE_CAPS_TEMPLATE_STRING \
RESAMPLE_CAPS_FLOAT " ; " \
RESAMPLE_CAPS_INT
static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (RESAMPLE_CAPS_TEMPLATE_STRING)
);
static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (RESAMPLE_CAPS_TEMPLATE_STRING)
);
static GstElement *
setup_speexresample (int channels, int inrate, int outrate, int width,
gboolean fp)
{
GstElement *speexresample;
GstCaps *caps;
GstStructure *structure;
GST_DEBUG ("setup_speexresample");
speexresample = gst_check_setup_element ("speexresample");
if (fp)
caps = gst_caps_from_string (RESAMPLE_CAPS_FLOAT);
else
caps = gst_caps_from_string (RESAMPLE_CAPS_INT);
structure = gst_caps_get_structure (caps, 0);
gst_structure_set (structure, "channels", G_TYPE_INT, channels,
"rate", G_TYPE_INT, inrate, "width", G_TYPE_INT, width, NULL);
if (!fp)
gst_structure_set (structure, "depth", G_TYPE_INT, width, NULL);
fail_unless (gst_caps_is_fixed (caps));
fail_unless (gst_element_set_state (speexresample,
GST_STATE_PAUSED) == GST_STATE_CHANGE_SUCCESS,
"could not set to paused");
mysrcpad = gst_check_setup_src_pad (speexresample, &srctemplate, caps);
gst_pad_set_caps (mysrcpad, caps);
gst_caps_unref (caps);
if (fp)
caps = gst_caps_from_string (RESAMPLE_CAPS_FLOAT);
else
caps = gst_caps_from_string (RESAMPLE_CAPS_INT);
structure = gst_caps_get_structure (caps, 0);
gst_structure_set (structure, "channels", G_TYPE_INT, channels,
"rate", G_TYPE_INT, outrate, "width", G_TYPE_INT, width, NULL);
if (!fp)
gst_structure_set (structure, "depth", G_TYPE_INT, width, NULL);
fail_unless (gst_caps_is_fixed (caps));
mysinkpad = gst_check_setup_sink_pad (speexresample, &sinktemplate, caps);
/* this installs a getcaps func that will always return the caps we set
* later */
gst_pad_set_caps (mysinkpad, caps);
gst_pad_use_fixed_caps (mysinkpad);
gst_pad_set_active (mysinkpad, TRUE);
gst_pad_set_active (mysrcpad, TRUE);
gst_caps_unref (caps);
return speexresample;
}
static void
cleanup_speexresample (GstElement * speexresample)
{
GST_DEBUG ("cleanup_speexresample");
fail_unless (gst_element_set_state (speexresample,
GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to NULL");
gst_pad_set_active (mysrcpad, FALSE);
gst_pad_set_active (mysinkpad, FALSE);
gst_check_teardown_src_pad (speexresample);
gst_check_teardown_sink_pad (speexresample);
gst_check_teardown_element (speexresample);
}
static void
fail_unless_perfect_stream (void)
{
guint64 timestamp = 0L, duration = 0L;
guint64 offset = 0L, offset_end = 0L;
GList *l;
GstBuffer *buffer;
for (l = buffers; l; l = l->next) {
buffer = GST_BUFFER (l->data);
ASSERT_BUFFER_REFCOUNT (buffer, "buffer", 1);
GST_DEBUG ("buffer timestamp %" G_GUINT64_FORMAT ", duration %"
G_GUINT64_FORMAT " offset %" G_GUINT64_FORMAT " offset_end %"
G_GUINT64_FORMAT,
GST_BUFFER_TIMESTAMP (buffer),
GST_BUFFER_DURATION (buffer),
GST_BUFFER_OFFSET (buffer), GST_BUFFER_OFFSET_END (buffer));
fail_unless_equals_uint64 (timestamp, GST_BUFFER_TIMESTAMP (buffer));
fail_unless_equals_uint64 (offset, GST_BUFFER_OFFSET (buffer));
duration = GST_BUFFER_DURATION (buffer);
offset_end = GST_BUFFER_OFFSET_END (buffer);
timestamp += duration;
offset = offset_end;
gst_buffer_unref (buffer);
}
g_list_free (buffers);
buffers = NULL;
}
/* this tests that the output is a perfect stream if the input is */
static void
test_perfect_stream_instance (int inrate, int outrate, int samples,
int numbuffers)
{
GstElement *speexresample;
GstBuffer *inbuffer, *outbuffer;
GstCaps *caps;
guint64 offset = 0;
int i, j;
gint16 *p;
speexresample = setup_speexresample (2, inrate, outrate, 16, FALSE);
caps = gst_pad_get_negotiated_caps (mysrcpad);
fail_unless (gst_caps_is_fixed (caps));
fail_unless (gst_element_set_state (speexresample,
GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
"could not set to playing");
for (j = 1; j <= numbuffers; ++j) {
inbuffer = gst_buffer_new_and_alloc (samples * 4);
GST_BUFFER_DURATION (inbuffer) = GST_FRAMES_TO_CLOCK_TIME (samples, inrate);
GST_BUFFER_TIMESTAMP (inbuffer) = GST_BUFFER_DURATION (inbuffer) * (j - 1);
GST_BUFFER_OFFSET (inbuffer) = offset;
offset += samples;
GST_BUFFER_OFFSET_END (inbuffer) = offset;
gst_buffer_set_caps (inbuffer, caps);
p = (gint16 *) GST_BUFFER_DATA (inbuffer);
/* create a 16 bit signed ramp */
for (i = 0; i < samples; ++i) {
*p = -32767 + i * (65535 / samples);
++p;
*p = -32767 + i * (65535 / samples);
++p;
}
/* pushing gives away my reference ... */
fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
/* ... but it ends up being collected on the global buffer list */
fail_unless_equals_int (g_list_length (buffers), j);
}
/* FIXME: we should make speexresample handle eos by flushing out the last
* samples, which will give us one more, small, buffer */
fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
ASSERT_BUFFER_REFCOUNT (outbuffer, "outbuffer", 1);
fail_unless_perfect_stream ();
/* cleanup */
gst_caps_unref (caps);
cleanup_speexresample (speexresample);
}
/* make sure that outgoing buffers are contiguous in timestamp/duration and
* offset/offsetend
*/
GST_START_TEST (test_perfect_stream)
{
/* integral scalings */
test_perfect_stream_instance (48000, 24000, 500, 20);
test_perfect_stream_instance (48000, 12000, 500, 20);
test_perfect_stream_instance (12000, 24000, 500, 20);
test_perfect_stream_instance (12000, 48000, 500, 20);
/* non-integral scalings */
test_perfect_stream_instance (44100, 8000, 500, 20);
test_perfect_stream_instance (8000, 44100, 500, 20);
/* wacky scalings */
test_perfect_stream_instance (12345, 54321, 500, 20);
test_perfect_stream_instance (101, 99, 500, 20);
}
GST_END_TEST;
/* this tests that the output is a correct discontinuous stream
* if the input is; ie input drops in time come out the same way */
static void
test_discont_stream_instance (int inrate, int outrate, int samples,
int numbuffers)
{
GstElement *speexresample;
GstBuffer *inbuffer, *outbuffer;
GstCaps *caps;
GstClockTime ints;
int i, j;
gint16 *p;
GST_DEBUG ("inrate:%d outrate:%d samples:%d numbuffers:%d",
inrate, outrate, samples, numbuffers);
speexresample = setup_speexresample (2, inrate, outrate, 16, FALSE);
caps = gst_pad_get_negotiated_caps (mysrcpad);
fail_unless (gst_caps_is_fixed (caps));
fail_unless (gst_element_set_state (speexresample,
GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
"could not set to playing");
for (j = 1; j <= numbuffers; ++j) {
inbuffer = gst_buffer_new_and_alloc (samples * 4);
GST_BUFFER_DURATION (inbuffer) = samples * GST_SECOND / inrate;
/* "drop" half the buffers */
ints = GST_BUFFER_DURATION (inbuffer) * 2 * (j - 1);
GST_BUFFER_TIMESTAMP (inbuffer) = ints;
GST_BUFFER_OFFSET (inbuffer) = (j - 1) * 2 * samples;
GST_BUFFER_OFFSET_END (inbuffer) = j * 2 * samples + samples;
gst_buffer_set_caps (inbuffer, caps);
p = (gint16 *) GST_BUFFER_DATA (inbuffer);
/* create a 16 bit signed ramp */
for (i = 0; i < samples; ++i) {
*p = -32767 + i * (65535 / samples);
++p;
*p = -32767 + i * (65535 / samples);
++p;
}
GST_DEBUG ("Sending Buffer time:%" G_GUINT64_FORMAT " duration:%"
G_GINT64_FORMAT " discont:%d offset:%" G_GUINT64_FORMAT " offset_end:%"
G_GUINT64_FORMAT, GST_BUFFER_TIMESTAMP (inbuffer),
GST_BUFFER_DURATION (inbuffer), GST_BUFFER_IS_DISCONT (inbuffer),
GST_BUFFER_OFFSET (inbuffer), GST_BUFFER_OFFSET_END (inbuffer));
/* pushing gives away my reference ... */
fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
/* check if the timestamp of the pushed buffer matches the incoming one */
outbuffer = g_list_nth_data (buffers, g_list_length (buffers) - 1);
fail_if (outbuffer == NULL);
fail_unless_equals_uint64 (ints, GST_BUFFER_TIMESTAMP (outbuffer));
GST_DEBUG ("Got Buffer time:%" G_GUINT64_FORMAT " duration:%"
G_GINT64_FORMAT " discont:%d offset:%" G_GUINT64_FORMAT " offset_end:%"
G_GUINT64_FORMAT, GST_BUFFER_TIMESTAMP (outbuffer),
GST_BUFFER_DURATION (outbuffer), GST_BUFFER_IS_DISCONT (outbuffer),
GST_BUFFER_OFFSET (outbuffer), GST_BUFFER_OFFSET_END (outbuffer));
if (j > 1) {
fail_unless (GST_BUFFER_IS_DISCONT (outbuffer),
"expected discont for buffer #%d", j);
}
}
/* cleanup */
gst_caps_unref (caps);
cleanup_speexresample (speexresample);
}
GST_START_TEST (test_discont_stream)
{
/* integral scalings */
test_discont_stream_instance (48000, 24000, 500, 20);
test_discont_stream_instance (48000, 12000, 500, 20);
test_discont_stream_instance (12000, 24000, 500, 20);
test_discont_stream_instance (12000, 48000, 500, 20);
/* non-integral scalings */
test_discont_stream_instance (44100, 8000, 500, 20);
test_discont_stream_instance (8000, 44100, 500, 20);
/* wacky scalings */
test_discont_stream_instance (12345, 54321, 500, 20);
test_discont_stream_instance (101, 99, 500, 20);
}
GST_END_TEST;
GST_START_TEST (test_reuse)
{
GstElement *speexresample;
GstEvent *newseg;
GstBuffer *inbuffer;
GstCaps *caps;
speexresample = setup_speexresample (1, 9343, 48000, 16, FALSE);
caps = gst_pad_get_negotiated_caps (mysrcpad);
fail_unless (gst_caps_is_fixed (caps));
fail_unless (gst_element_set_state (speexresample,
GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
"could not set to playing");
newseg = gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, 0, -1, 0);
fail_unless (gst_pad_push_event (mysrcpad, newseg) != FALSE);
inbuffer = gst_buffer_new_and_alloc (9343 * 4);
memset (GST_BUFFER_DATA (inbuffer), 0, GST_BUFFER_SIZE (inbuffer));
GST_BUFFER_DURATION (inbuffer) = GST_SECOND;
GST_BUFFER_TIMESTAMP (inbuffer) = 0;
GST_BUFFER_OFFSET (inbuffer) = 0;
gst_buffer_set_caps (inbuffer, caps);
/* pushing gives away my reference ... */
fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
/* ... but it ends up being collected on the global buffer list */
fail_unless_equals_int (g_list_length (buffers), 1);
/* now reset and try again ... */
fail_unless (gst_element_set_state (speexresample,
GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to NULL");
fail_unless (gst_element_set_state (speexresample,
GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
"could not set to playing");
newseg = gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, 0, -1, 0);
fail_unless (gst_pad_push_event (mysrcpad, newseg) != FALSE);
inbuffer = gst_buffer_new_and_alloc (9343 * 4);
memset (GST_BUFFER_DATA (inbuffer), 0, GST_BUFFER_SIZE (inbuffer));
GST_BUFFER_DURATION (inbuffer) = GST_SECOND;
GST_BUFFER_TIMESTAMP (inbuffer) = 0;
GST_BUFFER_OFFSET (inbuffer) = 0;
gst_buffer_set_caps (inbuffer, caps);
fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
/* ... it also ends up being collected on the global buffer list. If we
* now have more than 2 buffers, then speexresample probably didn't clean
* up its internal buffer properly and tried to push the remaining samples
* when it got the second NEWSEGMENT event */
fail_unless_equals_int (g_list_length (buffers), 2);
cleanup_speexresample (speexresample);
gst_caps_unref (caps);
}
GST_END_TEST;
GST_START_TEST (test_shutdown)
{
GstElement *pipeline, *src, *cf1, *ar, *cf2, *sink;
GstCaps *caps;
guint i;
/* create pipeline, force speexresample to actually resample */
pipeline = gst_pipeline_new (NULL);
src = gst_check_setup_element ("audiotestsrc");
cf1 = gst_check_setup_element ("capsfilter");
ar = gst_check_setup_element ("speexresample");
cf2 = gst_check_setup_element ("capsfilter");
g_object_set (cf2, "name", "capsfilter2", NULL);
sink = gst_check_setup_element ("fakesink");
caps =
gst_caps_new_simple ("audio/x-raw-int", "rate", G_TYPE_INT, 11025, NULL);
g_object_set (cf1, "caps", caps, NULL);
gst_caps_unref (caps);
caps =
gst_caps_new_simple ("audio/x-raw-int", "rate", G_TYPE_INT, 48000, NULL);
g_object_set (cf2, "caps", caps, NULL);
gst_caps_unref (caps);
/* don't want to sync against the clock, the more throughput the better */
g_object_set (src, "is-live", FALSE, NULL);
g_object_set (sink, "sync", FALSE, NULL);
gst_bin_add_many (GST_BIN (pipeline), src, cf1, ar, cf2, sink, NULL);
fail_if (!gst_element_link_many (src, cf1, ar, cf2, sink, NULL));
/* now, wait until pipeline is running and then shut it down again; repeat */
for (i = 0; i < 20; ++i) {
gst_element_set_state (pipeline, GST_STATE_PAUSED);
gst_element_get_state (pipeline, NULL, NULL, -1);
gst_element_set_state (pipeline, GST_STATE_PLAYING);
g_usleep (100);
gst_element_set_state (pipeline, GST_STATE_NULL);
}
gst_object_unref (pipeline);
}
GST_END_TEST;
static GstFlowReturn
live_switch_alloc_only_48000 (GstPad * pad, guint64 offset,
guint size, GstCaps * caps, GstBuffer ** buf)
{
GstStructure *structure;
gint rate;
gint channels;
GstCaps *desired;
structure = gst_caps_get_structure (caps, 0);
fail_unless (gst_structure_get_int (structure, "rate", &rate));
fail_unless (gst_structure_get_int (structure, "channels", &channels));
if (rate < 48000)
return GST_FLOW_NOT_NEGOTIATED;
desired = gst_caps_copy (caps);
gst_caps_set_simple (desired, "rate", G_TYPE_INT, 48000, NULL);
*buf = gst_buffer_new_and_alloc (channels * 48000);
gst_buffer_set_caps (*buf, desired);
gst_caps_unref (desired);
return GST_FLOW_OK;
}
static GstCaps *
live_switch_get_sink_caps (GstPad * pad)
{
GstCaps *result;
result = gst_caps_copy (GST_PAD_CAPS (pad));
gst_caps_set_simple (result,
"rate", GST_TYPE_INT_RANGE, 48000, G_MAXINT, NULL);
return result;
}
static void
live_switch_push (int rate, GstCaps * caps)
{
GstBuffer *inbuffer;
GstCaps *desired;
GList *l;
desired = gst_caps_copy (caps);
gst_caps_set_simple (desired, "rate", G_TYPE_INT, rate, NULL);
gst_pad_set_caps (mysrcpad, desired);
fail_unless (gst_pad_alloc_buffer_and_set_caps (mysrcpad,
GST_BUFFER_OFFSET_NONE, rate * 4, desired, &inbuffer) == GST_FLOW_OK);
/* When the basetransform hits the non-configured case it always
* returns a buffer with exactly the same caps as we requested so the actual
* renegotiation (if needed) will be done in the _chain*/
fail_unless (inbuffer != NULL);
GST_DEBUG ("desired: %" GST_PTR_FORMAT ".... got: %" GST_PTR_FORMAT,
desired, GST_BUFFER_CAPS (inbuffer));
fail_unless (gst_caps_is_equal (desired, GST_BUFFER_CAPS (inbuffer)));
memset (GST_BUFFER_DATA (inbuffer), 0, GST_BUFFER_SIZE (inbuffer));
GST_BUFFER_DURATION (inbuffer) = GST_SECOND;
GST_BUFFER_TIMESTAMP (inbuffer) = 0;
GST_BUFFER_OFFSET (inbuffer) = 0;
/* pushing gives away my reference ... */
fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
/* ... but it ends up being collected on the global buffer list */
fail_unless_equals_int (g_list_length (buffers), 1);
for (l = buffers; l; l = l->next) {
GstBuffer *buffer = GST_BUFFER (l->data);
gst_buffer_unref (buffer);
}
g_list_free (buffers);
buffers = NULL;
gst_caps_unref (desired);
}
GST_START_TEST (test_live_switch)
{
GstElement *speexresample;
GstEvent *newseg;
GstCaps *caps;
speexresample = setup_speexresample (4, 48000, 48000, 16, FALSE);
/* Let the sinkpad act like something that can only handle things of
* rate 48000- and can only allocate buffers for that rate, but if someone
* tries to get a buffer with a rate higher then 48000 tries to renegotiate
* */
gst_pad_set_bufferalloc_function (mysinkpad, live_switch_alloc_only_48000);
gst_pad_set_getcaps_function (mysinkpad, live_switch_get_sink_caps);
gst_pad_use_fixed_caps (mysrcpad);
caps = gst_pad_get_negotiated_caps (mysrcpad);
fail_unless (gst_caps_is_fixed (caps));
fail_unless (gst_element_set_state (speexresample,
GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
"could not set to playing");
newseg = gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, 0, -1, 0);
fail_unless (gst_pad_push_event (mysrcpad, newseg) != FALSE);
/* downstream can provide the requested rate, a buffer alloc will be passed
* on */
live_switch_push (48000, caps);
/* Downstream can never accept this rate, buffer alloc isn't passed on */
live_switch_push (40000, caps);
/* Downstream can provide the requested rate but will re-negotiate */
live_switch_push (50000, caps);
cleanup_speexresample (speexresample);
gst_caps_unref (caps);
}
GST_END_TEST;
#ifndef GST_DISABLE_PARSE
static GMainLoop *loop;
static gint messages = 0;
static void
element_message_cb (GstBus * bus, GstMessage * message, gpointer user_data)
{
gchar *s;
s = gst_structure_to_string (gst_message_get_structure (message));
GST_DEBUG ("Received message: %s", s);
g_free (s);
messages++;
}
static void
eos_message_cb (GstBus * bus, GstMessage * message, gpointer user_data)
{
GST_DEBUG ("Received eos");
g_main_loop_quit (loop);
}
static void
test_pipeline (gint width, gboolean fp, gint inrate, gint outrate, gint quality)
{
GstElement *pipeline;
GstBus *bus;
GError *error = NULL;
gchar *pipe_str;
pipe_str =
g_strdup_printf
("audiotestsrc num-buffers=10 ! audioconvert ! audio/x-raw-%s,rate=%d,width=%d,channels=2 ! speexresample quality=%d ! audio/x-raw-%s,rate=%d,width=%d ! identity check-imperfect-timestamp=TRUE ! fakesink",
(fp) ? "float" : "int", inrate, width, quality, (fp) ? "float" : "int",
outrate, width);
pipeline = gst_parse_launch (pipe_str, &error);
fail_unless (pipeline != NULL, "Error parsing pipeline: %s",
error ? error->message : "(invalid error)");
g_free (pipe_str);
bus = gst_element_get_bus (pipeline);
fail_if (bus == NULL);
gst_bus_add_signal_watch (bus);
g_signal_connect (bus, "message::element", (GCallback) element_message_cb,
NULL);
g_signal_connect (bus, "message::eos", (GCallback) eos_message_cb, NULL);
gst_element_set_state (pipeline, GST_STATE_PLAYING);
/* run until we receive EOS */
loop = g_main_loop_new (NULL, FALSE);
g_main_loop_run (loop);
g_main_loop_unref (loop);
loop = NULL;
gst_element_set_state (pipeline, GST_STATE_NULL);
fail_if (messages > 0, "Received imperfect timestamp messages");
gst_object_unref (pipeline);
}
GST_START_TEST (test_pipelines)
{
gint quality;
/* Test qualities 0, 5 and 10 */
for (quality = 0; quality < 11; quality += 5) {
test_pipeline (8, FALSE, 44100, 48000, quality);
test_pipeline (8, FALSE, 48000, 44100, quality);
test_pipeline (16, FALSE, 44100, 48000, quality);
test_pipeline (16, FALSE, 48000, 44100, quality);
test_pipeline (24, FALSE, 44100, 48000, quality);
test_pipeline (24, FALSE, 48000, 44100, quality);
test_pipeline (32, FALSE, 44100, 48000, quality);
test_pipeline (32, FALSE, 48000, 44100, quality);
test_pipeline (32, TRUE, 44100, 48000, quality);
test_pipeline (32, TRUE, 48000, 44100, quality);
test_pipeline (64, TRUE, 44100, 48000, quality);
test_pipeline (64, TRUE, 48000, 44100, quality);
}
}
GST_END_TEST;
#endif
static Suite *
speexresample_suite (void)
{
Suite *s = suite_create ("speexresample");
TCase *tc_chain = tcase_create ("general");
suite_add_tcase (s, tc_chain);
tcase_add_test (tc_chain, test_perfect_stream);
tcase_add_test (tc_chain, test_discont_stream);
tcase_add_test (tc_chain, test_reuse);
tcase_add_test (tc_chain, test_shutdown);
tcase_add_test (tc_chain, test_live_switch);
#ifndef GST_DISABLE_PARSE
tcase_set_timeout (tc_chain, 360);
tcase_add_test (tc_chain, test_pipelines);
#endif
return s;
}
GST_CHECK_MAIN (speexresample);