From: Stefan Kost Date: Wed, 25 May 2011 20:40:26 +0000 (+0300) Subject: audiotestsrc: add red (brownian) noise generator X-Git-Tag: 1.19.3~511^2~6555^2~850 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1cf831e74ec1231137ec3cbbd8b8cab5eb0c4749;p=platform%2Fupstream%2Fgstreamer.git audiotestsrc: add red (brownian) noise generator Add another noise generator which produces a quite dark noise color. Fixes parts of #649969. --- diff --git a/gst/audiotestsrc/gstaudiotestsrc.c b/gst/audiotestsrc/gstaudiotestsrc.c index ecbb2fb..1570c59 100644 --- a/gst/audiotestsrc/gstaudiotestsrc.c +++ b/gst/audiotestsrc/gstaudiotestsrc.c @@ -130,6 +130,7 @@ gst_audiostestsrc_wave_get_type (void) {GST_AUDIO_TEST_SRC_WAVE_TICKS, "Periodic Ticks", "ticks"}, {GST_AUDIO_TEST_SRC_WAVE_GAUSSIAN_WHITE_NOISE, "White Gaussian noise", "gaussian-noise"}, + {GST_AUDIO_TEST_SRC_WAVE_RED_NOISE, "Red (brownian) noise", "red-noise"}, {0, NULL, NULL}, }; @@ -837,6 +838,49 @@ static const ProcessFunc gaussian_white_noise_funcs[] = { (ProcessFunc) gst_audio_test_src_create_gaussian_white_noise_double }; +/* Brownian (Red) Noise: noise where the power density decreases by 6 dB per + * octave with increasing frequency + * + * taken from http://vellocet.com/dsp/noise/VRand.html + * by Andrew Simper of Vellocet (andy@vellocet.com) + */ + +#define DEFINE_RED_NOISE(type,scale) \ +static void \ +gst_audio_test_src_create_red_noise_##type (GstAudioTestSrc * src, g##type * samples) \ +{ \ + gint i, c; \ + gdouble amp = (src->volume * scale); \ + gdouble state = src->red.state; \ + \ + for (i = 0; i < src->generate_samples_per_buffer * src->channels; ) { \ + for (c = 0; c < src->channels; ++c) { \ + while (TRUE) { \ + gdouble r = g_rand_double_range (src->gen, -1.0, 1.0); \ + state += r; \ + if (state<-8.0f || state>8.0f) state -= r; \ + else break; \ + } \ + samples[i++] = (g##type) (amp * state * 0.0625f); /* /16.0 */ \ + } \ + } \ + src->red.state = state; \ +} + +DEFINE_RED_NOISE (int16, 32767.0); +DEFINE_RED_NOISE (int32, 2147483647.0); +DEFINE_RED_NOISE (float, 1.0); +DEFINE_RED_NOISE (double, 1.0); + +static const ProcessFunc red_noise_funcs[] = { + (ProcessFunc) gst_audio_test_src_create_red_noise_int16, + (ProcessFunc) gst_audio_test_src_create_red_noise_int32, + (ProcessFunc) gst_audio_test_src_create_red_noise_float, + (ProcessFunc) gst_audio_test_src_create_red_noise_double +}; + + + /* * gst_audio_test_src_change_wave: * Assign function pointer of wave genrator. @@ -889,6 +933,12 @@ gst_audio_test_src_change_wave (GstAudioTestSrc * src) src->gen = g_rand_new (); src->process = gaussian_white_noise_funcs[src->format]; break; + case GST_AUDIO_TEST_SRC_WAVE_RED_NOISE: + if (!(src->gen)) + src->gen = g_rand_new (); + src->red.state = 0.0; + src->process = red_noise_funcs[src->format]; + break; default: GST_ERROR ("invalid wave-form"); break; diff --git a/gst/audiotestsrc/gstaudiotestsrc.h b/gst/audiotestsrc/gstaudiotestsrc.h index 8c76594..971fe77 100644 --- a/gst/audiotestsrc/gstaudiotestsrc.h +++ b/gst/audiotestsrc/gstaudiotestsrc.h @@ -50,6 +50,7 @@ G_BEGIN_DECLS * @GST_AUDIO_TEST_SRC_WAVE_SINE_TAB: sine wave using a table * @GST_AUDIO_TEST_SRC_WAVE_TICKS: periodic ticks * @GST_AUDIO_TEST_SRC_WAVE_GAUSSIAN_WHITE_NOISE: white (zero mean) Gaussian noise; volume sets the standard deviation of the noise in units of the range of values of the sample type, e.g. volume=0.1 produces noise with a standard deviation of 0.1*32767=3277 with 16-bit integer samples, or 0.1*1.0=0.1 with floating-point samples. + * @GST_AUDIO_TEST_SRC_WAVE_RED_NOISE: red (brownian) noise * * Different types of supported sound waves. */ @@ -63,8 +64,9 @@ typedef enum { GST_AUDIO_TEST_SRC_WAVE_PINK_NOISE, GST_AUDIO_TEST_SRC_WAVE_SINE_TAB, GST_AUDIO_TEST_SRC_WAVE_TICKS, - GST_AUDIO_TEST_SRC_WAVE_GAUSSIAN_WHITE_NOISE -} GstAudioTestSrcWave; + GST_AUDIO_TEST_SRC_WAVE_GAUSSIAN_WHITE_NOISE, + GST_AUDIO_TEST_SRC_WAVE_RED_NOISE +} GstAudioTestSrcWave; #define PINK_MAX_RANDOM_ROWS (30) #define PINK_RANDOM_BITS (16) @@ -78,6 +80,10 @@ typedef struct { gdouble scalar; /* Used to scale within range of -1.0 to +1.0 */ } GstPinkNoise; +typedef struct { + gdouble state; /* noise state */ +} GstRedNoise; + typedef enum { GST_AUDIO_TEST_SRC_FORMAT_NONE = -1, GST_AUDIO_TEST_SRC_FORMAT_S16 = 0, @@ -105,14 +111,14 @@ struct _GstAudioTestSrc { GstAudioTestSrcWave wave; gdouble volume; gdouble freq; - + /* audio parameters */ gint channels; gint samplerate; gint samples_per_buffer; gint sample_size; GstAudioTestSrcFormat format; - + /*< private >*/ gboolean tags_pushed; /* send tags just once ? */ GstClockTimeDiff timestamp_offset; /* base offset */ @@ -125,11 +131,12 @@ struct _GstAudioTestSrc { gint generate_samples_per_buffer; /* used to generate a partial buffer */ gboolean can_activate_pull; gboolean reverse; /* play backwards */ - + /* waveform specific context data */ GRand *gen; /* random number generator */ gdouble accumulator; /* phase angle */ GstPinkNoise pink; + GstRedNoise red; gdouble wave_table[1024]; };