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.
This commit is contained in:
Leo Singer 2011-02-18 13:27:23 -08:00 committed by Sebastian Dröge
parent 0e3c32ac72
commit 82199c5815
2 changed files with 34 additions and 7 deletions

View file

@ -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:

View file

@ -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];