diff options
Diffstat (limited to 'gst')
-rw-r--r-- | gst/speexresample/Makefile.am | 13 | ||||
-rw-r--r-- | gst/speexresample/gstspeexresample.c | 209 | ||||
-rw-r--r-- | gst/speexresample/gstspeexresample.h | 2 | ||||
-rw-r--r-- | gst/speexresample/resample.c | 2 | ||||
-rw-r--r-- | gst/speexresample/speex_resampler_double.c | 2 | ||||
-rw-r--r-- | gst/speexresample/speex_resampler_float.c | 2 | ||||
-rw-r--r-- | gst/speexresample/speex_resampler_int.c | 2 | ||||
-rw-r--r-- | gst/speexresample/speex_resampler_wrapper.h | 2 |
8 files changed, 210 insertions, 24 deletions
diff --git a/gst/speexresample/Makefile.am b/gst/speexresample/Makefile.am index f4d1534d..161de621 100644 --- a/gst/speexresample/Makefile.am +++ b/gst/speexresample/Makefile.am @@ -9,24 +9,29 @@ libgstspeexresample_la_SOURCES = \ libgstspeexresample_la_CFLAGS = \ $(GST_PLUGINS_BASE_CFLAGS) \ $(GST_BASE_CFLAGS) \ - $(GST_CFLAGS) + $(GST_CFLAGS) \ + $(LIBOIL_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) 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 - diff --git a/gst/speexresample/gstspeexresample.c b/gst/speexresample/gstspeexresample.c index 7d04257a..f2fa4859 100644 --- a/gst/speexresample/gstspeexresample.c +++ b/gst/speexresample/gstspeexresample.c @@ -1,7 +1,7 @@ /* GStreamer * Copyright (C) 1999 Erik Walthinsen <omega@cse.ogi.edu> * Copyright (C) 2003,2004 David A. Schleef <ds@schleef.org> - * Copyright (C) 2007 Sebastian Dröge <slomo@circular-chaos.org> + * 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 @@ -45,6 +45,10 @@ #include <gst/audio/audio.h> #include <gst/base/gstbasetransform.h> +#define OIL_ENABLE_UNSTABLE_API +#include <liboil/liboilprofile.h> +#include <liboil/liboil.h> + GST_DEBUG_CATEGORY (speex_resample_debug); #define GST_CAT_DEFAULT speex_resample_debug @@ -91,6 +95,9 @@ GST_STATIC_CAPS ( \ "signed = (boolean) true" \ ) +/* If TRUE integer arithmetic resampling is faster and will be used if appropiate */ +static gboolean gst_speex_resample_use_int = FALSE; + static GstStaticPadTemplate gst_speex_resample_sink_template = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, SUPPORTED_CAPS); @@ -125,11 +132,8 @@ 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); +GST_BOILERPLATE (GstSpeexResample, gst_speex_resample, GstBaseTransform, + GST_TYPE_BASE_TRANSFORM); static void gst_speex_resample_base_init (gpointer g_class) @@ -143,7 +147,7 @@ gst_speex_resample_base_init (gpointer g_class) gst_element_class_set_details_simple (gstelement_class, "Audio resampler", "Filter/Converter/Audio", "Resamples audio", - "Sebastian Dröge <slomo@circular-chaos.org>"); + "Sebastian Dröge <sebastian.droege@collabora.co.uk>"); } static void @@ -297,9 +301,10 @@ gst_speex_resample_get_funcs (gint width, gboolean fp) { const SpeexResampleFuncs *funcs = NULL; - if ((width == 8 || width == 16) && !fp) + if (gst_speex_resample_use_int && (width == 8 || width == 16) && !fp) funcs = &int_funcs; - else if (width == 32 && fp) + else if ((!gst_speex_resample_use_int && (width == 8 || width == 16) && !fp) + || (width == 32 && fp)) funcs = &float_funcs; else if ((width == 64 && fp) || ((width == 32 || width == 24) && !fp)) funcs = &double_funcs; @@ -572,7 +577,7 @@ gst_speex_resample_convert_buffer (GstSpeexResample * resample, len *= resample->channels; if (inverse) { - if (resample->width == 8 && !resample->fp) { + if (gst_speex_resample_use_int && resample->width == 8 && !resample->fp) { gint8 *o = (gint8 *) out; gint16 *i = (gint16 *) in; gint32 tmp; @@ -584,6 +589,32 @@ gst_speex_resample_convert_buffer (GstSpeexResample * resample, i++; len--; } + } else if (!gst_speex_resample_use_int && resample->width == 8 + && !resample->fp) { + gint8 *o = (gint8 *) out; + gfloat *i = (gfloat *) in; + gfloat tmp; + + while (len) { + tmp = *i; + *o = (gint8) CLAMP (tmp * G_MAXINT8 + 0.5, G_MININT8, G_MAXINT8); + o++; + i++; + len--; + } + } else if (!gst_speex_resample_use_int && resample->width == 16 + && !resample->fp) { + gint16 *o = (gint16 *) out; + gfloat *i = (gfloat *) in; + gfloat tmp; + + while (len) { + tmp = *i; + *o = (gint16) CLAMP (tmp * G_MAXINT16 + 0.5, G_MININT16, G_MAXINT16); + o++; + i++; + len--; + } } else if (resample->width == 24 && !resample->fp) { guint8 *o = (guint8 *) out; gdouble *i = (gdouble *) in; @@ -591,8 +622,8 @@ gst_speex_resample_convert_buffer (GstSpeexResample * resample, while (len) { tmp = *i; - GST_WRITE_UINT24 (o, CLAMP (tmp * GST_MAXINT24 + 0.5, GST_MININT24, - GST_MAXINT24)); + GST_WRITE_UINT24 (o, (gint32) CLAMP (tmp * GST_MAXINT24 + 0.5, + GST_MININT24, GST_MAXINT24)); o += 3; i++; len--; @@ -604,14 +635,14 @@ gst_speex_resample_convert_buffer (GstSpeexResample * resample, while (len) { tmp = *i; - *o = CLAMP (tmp * G_MAXINT32 + 0.5, G_MININT32, G_MAXINT32); + *o = (gint32) CLAMP (tmp * G_MAXINT32 + 0.5, G_MININT32, G_MAXINT32); o++; i++; len--; } } } else { - if (resample->width == 8 && !resample->fp) { + if (gst_speex_resample_use_int && resample->width == 8 && !resample->fp) { gint8 *i = (gint8 *) in; gint16 *o = (gint16 *) out; gint32 tmp; @@ -623,6 +654,32 @@ gst_speex_resample_convert_buffer (GstSpeexResample * resample, i++; len--; } + } else if (!gst_speex_resample_use_int && resample->width == 8 + && !resample->fp) { + gint8 *i = (gint8 *) in; + gfloat *o = (gfloat *) out; + gfloat tmp; + + while (len) { + tmp = *i; + *o = tmp / G_MAXINT8; + o++; + i++; + len--; + } + } else if (!gst_speex_resample_use_int && resample->width == 16 + && !resample->fp) { + gint16 *i = (gint16 *) in; + gfloat *o = (gfloat *) out; + gfloat tmp; + + while (len) { + tmp = *i; + *o = tmp / G_MAXINT16; + o++; + i++; + len--; + } } else if (resample->width == 24 && !resample->fp) { guint8 *i = (guint8 *) in; gdouble *o = (gdouble *) out; @@ -1117,10 +1174,134 @@ gst_speex_resample_get_property (GObject * object, guint prop_id, } } +#define BENCHMARK_SIZE 512 + +static gboolean +_benchmark_int_float (SpeexResamplerState * st) +{ + gint16 in[BENCHMARK_SIZE] = { 0, }, out[BENCHMARK_SIZE / 2]; + gfloat in_tmp[BENCHMARK_SIZE], out_tmp[BENCHMARK_SIZE / 2]; + gint i; + guint32 inlen = BENCHMARK_SIZE, outlen = BENCHMARK_SIZE / 2; + + for (i = 0; i < BENCHMARK_SIZE; i++) { + gfloat tmp = in[i]; + in_tmp[i] = tmp / G_MAXINT16; + } + + resample_float_resampler_process_interleaved_float (st, + (const guint8 *) in_tmp, &inlen, (guint8 *) out_tmp, &outlen); + + if (outlen == 0) { + GST_ERROR ("Failed to use float resampler"); + return FALSE; + } + + for (i = 0; i < outlen; i++) { + gfloat tmp = out_tmp[i]; + out[i] = CLAMP (tmp * G_MAXINT16 + 0.5, G_MININT16, G_MAXINT16); + } + + return TRUE; +} + +static gboolean +_benchmark_int_int (SpeexResamplerState * st) +{ + gint16 in[BENCHMARK_SIZE] = { 0, }, out[BENCHMARK_SIZE / 2]; + guint32 inlen = BENCHMARK_SIZE, outlen = BENCHMARK_SIZE / 2; + + resample_int_resampler_process_interleaved_int (st, (const guint8 *) in, + &inlen, (guint8 *) out, &outlen); + + if (outlen == 0) { + GST_ERROR ("Failed to use int resampler"); + return FALSE; + } + + return TRUE; +} + +static gboolean +_benchmark_integer_resampling (void) +{ + OilProfile a, b; + gdouble av, bv; + SpeexResamplerState *sta, *stb; + + oil_profile_init (&a); + oil_profile_init (&b); + + sta = resample_float_resampler_init (1, 48000, 24000, 4, NULL); + if (sta == NULL) { + GST_ERROR ("Failed to create float resampler state"); + return FALSE; + } + + stb = resample_int_resampler_init (1, 48000, 24000, 4, NULL); + if (stb == NULL) { + resample_float_resampler_destroy (sta); + GST_ERROR ("Failed to create int resampler state"); + return FALSE; + } + + /* Warm up cache */ + if (!_benchmark_int_float (sta)) + goto error; + if (!_benchmark_int_float (sta)) + goto error; + + /* Benchmark */ + oil_profile_start (&a); + if (!_benchmark_int_float (sta)) + goto error; + oil_profile_stop (&a); + + /* Warm up cache */ + if (!_benchmark_int_int (stb)) + goto error; + if (!_benchmark_int_int (stb)) + goto error; + + /* Benchmark */ + oil_profile_start (&b); + if (!_benchmark_int_int (stb)) + goto error; + oil_profile_stop (&b); + + /* Handle results */ + oil_profile_get_ave_std (&a, &av, NULL); + oil_profile_get_ave_std (&b, &bv, NULL); + + gst_speex_resample_use_int = (av > bv); + resample_float_resampler_destroy (sta); + resample_float_resampler_destroy (stb); + + if (av > bv) + GST_DEBUG ("Using integer resampler if appropiate: %lf < %lf", bv, av); + else + GST_DEBUG ("Using float resampler for everything: %lf <= %lf", av, bv); + + return TRUE; + +error: + resample_float_resampler_destroy (sta); + resample_float_resampler_destroy (stb); + + return FALSE; +} static gboolean plugin_init (GstPlugin * plugin) { + GST_DEBUG_CATEGORY_INIT (speex_resample_debug, "speex_resample", 0, + "audio resampling element"); + + oil_init (); + + if (!_benchmark_integer_resampling ()) + return FALSE; + if (!gst_element_register (plugin, "speexresample", GST_RANK_NONE, GST_TYPE_SPEEX_RESAMPLE)) { return FALSE; diff --git a/gst/speexresample/gstspeexresample.h b/gst/speexresample/gstspeexresample.h index 1cf2196c..e39148a0 100644 --- a/gst/speexresample/gstspeexresample.h +++ b/gst/speexresample/gstspeexresample.h @@ -1,6 +1,6 @@ /* GStreamer * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu> - * Copyright (C) <2007> Sebastian Dröge <slomo@circular-chaos.org> + * 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 diff --git a/gst/speexresample/resample.c b/gst/speexresample/resample.c index 6f172509..f29e6144 100644 --- a/gst/speexresample/resample.c +++ b/gst/speexresample/resample.c @@ -66,7 +66,7 @@ #include <glib.h> -#define EXPORT +#define EXPORT G_GNUC_INTERNAL static inline void * speex_alloc (int size) diff --git a/gst/speexresample/speex_resampler_double.c b/gst/speexresample/speex_resampler_double.c index 39e242d8..e5a25714 100644 --- a/gst/speexresample/speex_resampler_double.c +++ b/gst/speexresample/speex_resampler_double.c @@ -1,5 +1,5 @@ /* GStreamer - * Copyright (C) 2007 Sebastian Dröge <slomo@circular-chaos.org> + * 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 diff --git a/gst/speexresample/speex_resampler_float.c b/gst/speexresample/speex_resampler_float.c index 281e52d3..f13f60c5 100644 --- a/gst/speexresample/speex_resampler_float.c +++ b/gst/speexresample/speex_resampler_float.c @@ -1,5 +1,5 @@ /* GStreamer - * Copyright (C) 2007 Sebastian Dröge <slomo@circular-chaos.org> + * 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 diff --git a/gst/speexresample/speex_resampler_int.c b/gst/speexresample/speex_resampler_int.c index c992f0a6..6b858604 100644 --- a/gst/speexresample/speex_resampler_int.c +++ b/gst/speexresample/speex_resampler_int.c @@ -1,5 +1,5 @@ /* GStreamer - * Copyright (C) 2007 Sebastian Dröge <slomo@circular-chaos.org> + * 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 diff --git a/gst/speexresample/speex_resampler_wrapper.h b/gst/speexresample/speex_resampler_wrapper.h index 2cf79b0e..36d444f8 100644 --- a/gst/speexresample/speex_resampler_wrapper.h +++ b/gst/speexresample/speex_resampler_wrapper.h @@ -1,5 +1,5 @@ /* GStreamer - * Copyright (C) 2007 Sebastian Dröge <slomo@circular-chaos.org> + * 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 |