From 82199c581506a6ef3f21144c6a7f48aea0f22240 Mon Sep 17 00:00:00 2001 From: Leo Singer Date: Fri, 18 Feb 2011 13:27:23 -0800 Subject: [PATCH] audiotestsrc: each element gets its own instance of GRand, if needed As a result, pipelines that contain multiple instances of audiotestsrc with the 'wave' property set to 'white-noise', 'pink-noise', or 'gaussian-noise' will run much faster, since they won't be competing for access to the global, lock-protected instance of GRand. Fixes bug #642720. --- gst/audiotestsrc/gstaudiotestsrc.c | 40 ++++++++++++++++++++++++------ gst/audiotestsrc/gstaudiotestsrc.h | 1 + 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/gst/audiotestsrc/gstaudiotestsrc.c b/gst/audiotestsrc/gstaudiotestsrc.c index 5b689713fb..ecbb2fbb07 100644 --- a/gst/audiotestsrc/gstaudiotestsrc.c +++ b/gst/audiotestsrc/gstaudiotestsrc.c @@ -140,6 +140,8 @@ gst_audiostestsrc_wave_get_type (void) return audiostestsrc_wave_type; } +static void gst_audio_test_src_finalize (GObject * object); + static void gst_audio_test_src_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); static void gst_audio_test_src_get_property (GObject * object, @@ -190,6 +192,7 @@ gst_audio_test_src_class_init (GstAudioTestSrcClass * klass) gobject_class->set_property = gst_audio_test_src_set_property; gobject_class->get_property = gst_audio_test_src_get_property; + gobject_class->finalize = gst_audio_test_src_finalize; g_object_class_install_property (gobject_class, PROP_SAMPLES_PER_BUFFER, g_param_spec_int ("samplesperbuffer", "Samples per buffer", @@ -263,10 +266,24 @@ gst_audio_test_src_init (GstAudioTestSrc * src, GstAudioTestSrcClass * g_class) src->timestamp_offset = DEFAULT_TIMESTAMP_OFFSET; src->can_activate_pull = DEFAULT_CAN_ACTIVATE_PULL; + src->gen = NULL; + src->wave = DEFAULT_WAVE; gst_base_src_set_blocksize (GST_BASE_SRC (src), -1); } +static void +gst_audio_test_src_finalize (GObject * object) +{ + GstAudioTestSrc *src = GST_AUDIO_TEST_SRC (object); + + if (src->gen) + g_rand_free (src->gen); + src->gen = NULL; + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + static void gst_audio_test_src_src_fixate (GstPad * pad, GstCaps * caps) { @@ -584,7 +601,7 @@ gst_audio_test_src_create_white_noise_##type (GstAudioTestSrc * src, g##type * s i = 0; \ while (i < (src->generate_samples_per_buffer * src->channels)) { \ for (c = 0; c < src->channels; ++c) \ - samples[i++] = (g##type) (amp * g_random_double_range (-1.0, 1.0)); \ + samples[i++] = (g##type) (amp * g_rand_double_range (src->gen, -1.0, 1.0)); \ } \ } @@ -626,8 +643,9 @@ gst_audio_test_src_init_pink_noise (GstAudioTestSrc * src) /* Generate Pink noise values between -1.0 and +1.0 */ static gdouble -gst_audio_test_src_generate_pink_noise_value (GstPinkNoise * pink) +gst_audio_test_src_generate_pink_noise_value (GstAudioTestSrc * src) { + GstPinkNoise *pink = &src->pink; glong new_random; glong sum; @@ -651,13 +669,15 @@ gst_audio_test_src_generate_pink_noise_value (GstPinkNoise * pink) * values together. Only one changes each time. */ pink->running_sum -= pink->rows[num_zeros]; - new_random = 32768.0 - (65536.0 * (gulong) rand () / (RAND_MAX + 1.0)); + new_random = 32768.0 - (65536.0 * (gulong) g_rand_int (src->gen) + / (G_MAXUINT32 + 1.0)); pink->running_sum += new_random; pink->rows[num_zeros] = new_random; } /* Add extra white noise value. */ - new_random = 32768.0 - (65536.0 * (gulong) rand () / (RAND_MAX + 1.0)); + new_random = 32768.0 - (65536.0 * (gulong) g_rand_int (src->gen) + / (G_MAXUINT32 + 1.0)); sum = pink->running_sum + new_random; /* Scale to range of -1.0 to 0.9999. */ @@ -677,7 +697,7 @@ gst_audio_test_src_create_pink_noise_##type (GstAudioTestSrc * src, g##type * sa while (i < (src->generate_samples_per_buffer * src->channels)) { \ for (c = 0; c < src->channels; ++c) { \ samples[i++] = \ - (g##type) (gst_audio_test_src_generate_pink_noise_value (&src->pink) * \ + (g##type) (gst_audio_test_src_generate_pink_noise_value (src) * \ amp); \ } \ } \ @@ -794,8 +814,8 @@ gst_audio_test_src_create_gaussian_white_noise_##type (GstAudioTestSrc * src, g# \ for (i = 0; i < src->generate_samples_per_buffer * src->channels; ) { \ for (c = 0; c < src->channels; ++c) { \ - gdouble mag = sqrt (-2 * log (1.0 - g_random_double ())); \ - gdouble phs = g_random_double_range (0.0, M_PI_M2); \ + gdouble mag = sqrt (-2 * log (1.0 - g_rand_double (src->gen))); \ + gdouble phs = g_rand_double_range (src->gen, 0.0, M_PI_M2); \ \ samples[i++] = (g##type) (amp * mag * cos (phs)); \ if (++c >= src->channels) \ @@ -846,9 +866,13 @@ gst_audio_test_src_change_wave (GstAudioTestSrc * src) src->process = silence_funcs[src->format]; break; case GST_AUDIO_TEST_SRC_WAVE_WHITE_NOISE: + if (!(src->gen)) + src->gen = g_rand_new (); src->process = white_noise_funcs[src->format]; break; case GST_AUDIO_TEST_SRC_WAVE_PINK_NOISE: + if (!(src->gen)) + src->gen = g_rand_new (); gst_audio_test_src_init_pink_noise (src); src->process = pink_noise_funcs[src->format]; break; @@ -861,6 +885,8 @@ gst_audio_test_src_change_wave (GstAudioTestSrc * src) src->process = tick_funcs[src->format]; break; case GST_AUDIO_TEST_SRC_WAVE_GAUSSIAN_WHITE_NOISE: + if (!(src->gen)) + src->gen = g_rand_new (); src->process = gaussian_white_noise_funcs[src->format]; break; default: diff --git a/gst/audiotestsrc/gstaudiotestsrc.h b/gst/audiotestsrc/gstaudiotestsrc.h index 860c5c01b1..8c76594822 100644 --- a/gst/audiotestsrc/gstaudiotestsrc.h +++ b/gst/audiotestsrc/gstaudiotestsrc.h @@ -127,6 +127,7 @@ struct _GstAudioTestSrc { gboolean reverse; /* play backwards */ /* waveform specific context data */ + GRand *gen; /* random number generator */ gdouble accumulator; /* phase angle */ GstPinkNoise pink; gdouble wave_table[1024];