+2008-07-23 Sebastian Dröge <sebastian.droege@collabora.co.uk>
+
+ * gst/audioconvert/audioconvert.h:
+ * gst/audioconvert/gstaudioquantize.c:
+ (gst_audio_quantize_setup_dither),
+ (gst_audio_quantize_free_dither):
+ * gst/audioconvert/gstfastrandom.h:
+ Implement a linear congruential generator as pseudo random number
+ generator for the dither noise. This is about 2 times faster than
+ using GLib's mersenne twister. Also this uses only integer math for
+ generating integers while GLib internally uses floating point math.
+
2008-07-23 Michael Smith <msmith@songbirdnest.com>
* configure.ac:
#include "audioconvert.h"
#include "gstaudioquantize.h"
+#include "gstfastrandom.h"
+
#define MAKE_QUANTIZE_FUNC_NAME(name) \
gst_audio_quantize_quantize_##name
gint32 dither = (1<<(scale));
#define ADD_DITHER_RPDF_I() \
- rand = g_rand_int_range (ctx->dither_random, bias - dither, \
- bias + dither); \
+ rand = gst_fast_random_int32_range (bias - dither, \
+ bias + dither); \
if (rand > 0 && tmp > 0 && G_MAXINT32 - tmp <= rand) \
tmp = G_MAXINT32; \
else if (rand < 0 && tmp < 0 && G_MININT32 - tmp >= rand) \
gdouble dither = 1.0/(1U<<(32 - scale - 1));
#define ADD_DITHER_RPDF_F() \
- tmp += g_rand_double_range (ctx->dither_random, - dither, \
- dither);
+ tmp += gst_fast_random_double_range (- dither, dither);
#define INIT_DITHER_TPDF_I() \
gint32 rand; \
bias = bias >> 1;
#define ADD_DITHER_TPDF_I() \
- rand = g_rand_int_range (ctx->dither_random, bias - dither, \
- bias + dither - 1) \
- + g_rand_int_range (ctx->dither_random, bias - dither, \
- bias + dither - 1); \
+ rand = gst_fast_random_int32_range (bias - dither, \
+ bias + dither - 1) \
+ + gst_fast_random_int32_range (bias - dither, \
+ bias + dither - 1); \
if (rand > 0 && tmp > 0 && G_MAXINT32 - tmp <= rand) \
tmp = G_MAXINT32; \
else if (rand < 0 && tmp < 0 && G_MININT32 - tmp >= rand) \
gdouble dither = 1.0/(1U<<(32 - scale));
#define ADD_DITHER_TPDF_F() \
- tmp += g_rand_double_range (ctx->dither_random, - dither, \
- dither) \
- + g_rand_double_range (ctx->dither_random, - dither, \
- dither);
+ tmp += gst_fast_random_double_range (- dither, dither) \
+ + gst_fast_random_double_range (- dither, dither);
#define INIT_DITHER_TPDF_HF_I() \
gint32 rand; \
bias = bias >> 1;
#define ADD_DITHER_TPDF_HF_I() \
- tmp_rand = g_rand_int_range (ctx->dither_random, bias - dither, \
- bias + dither); \
+ tmp_rand = gst_fast_random_int32_range (bias - dither, \
+ bias + dither); \
rand = tmp_rand - last_random[chan_pos]; \
last_random[chan_pos] = tmp_rand; \
if (rand > 0 && tmp > 0 && G_MAXINT32 - tmp <= rand) \
gdouble *last_random = (gdouble *) ctx->last_random, tmp_rand;
#define ADD_DITHER_TPDF_HF_F() \
- tmp_rand = g_rand_double_range (ctx->dither_random, - dither, \
- dither); \
+ tmp_rand = gst_fast_random_double_range (- dither, dither); \
rand = tmp_rand - last_random[chan_pos]; \
last_random[chan_pos] = tmp_rand; \
tmp += rand;
ctx->last_random = g_new0 (gint32, ctx->out.channels);
else
ctx->last_random = g_new0 (gdouble, ctx->out.channels);
- ctx->dither_random = g_rand_new ();
break;
case DITHER_RPDF:
case DITHER_TPDF:
- ctx->dither_random = g_rand_new ();
ctx->last_random = NULL;
break;
case DITHER_NONE:
default:
- ctx->dither_random = NULL;
ctx->last_random = NULL;
break;
}
gst_audio_quantize_free_dither (AudioConvertCtx * ctx)
{
g_free (ctx->last_random);
- if (ctx->dither_random)
- g_rand_free (ctx->dither_random);
return;
}
--- /dev/null
+/* GStreamer
+ * Copyright (C) 2008 Sebastian Dröge <sebastian.droege@collabora.co.uk>
+ *
+ * gstfastrandom.h: Fast, bad PNRG
+ *
+ * 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 <glib.h>
+
+#ifndef __GST_FAST_RANDOM__
+#define __GST_FAST_RANDOM__
+
+/* transform [0..2^32] -> [0..1] */
+#define GST_RAND_DOUBLE_TRANSFORM 2.3283064365386962890625e-10
+
+/* This is the base function, implementing a linear congruential generator
+ * and returning a pseudo random number between 0 and 2^32 - 1.
+ */
+static inline guint32
+gst_fast_random_uint32 ()
+{
+ static guint32 state = 0xdeadbeef;
+
+ return (state = state * 1103515245 + 12345);
+}
+
+static inline guint32
+gst_fast_random_uint32_range (gint32 start, gint32 end)
+{
+ guint64 tmp = gst_fast_random_uint32 ();
+
+ tmp = (tmp * (end - start)) / G_MAXUINT32 + start;
+
+ return (guint32) tmp;
+}
+
+static inline gint32
+gst_fast_random_int32 (void)
+{
+ return (gint32) gst_fast_random_uint32 ();
+}
+
+static inline gint32
+gst_fast_random_int32_range (gint32 start, gint32 end)
+{
+ gint64 tmp = gst_fast_random_uint32 ();
+
+ tmp = (tmp * (end - start)) / G_MAXUINT32 + start;
+
+ return (gint32) tmp;
+}
+
+static inline gdouble
+gst_fast_random_double (void)
+{
+ gdouble ret;
+
+ ret = gst_fast_random_uint32 () * GST_RAND_DOUBLE_TRANSFORM;
+ ret = (ret + gst_fast_random_uint32 ()) * GST_RAND_DOUBLE_TRANSFORM;
+
+ if (ret >= 1.0)
+ return gst_fast_random_double ();
+
+ return ret;
+}
+
+static inline gdouble
+gst_fast_random_double_range (gdouble start, gdouble end)
+{
+ return gst_fast_random_double () * (end - start) + start;
+}
+
+#undef GST_RAND_DOUBLE_TRANSFORM
+
+#endif /* __GST_FAST_RANDOM__ */
+