audiotestsrc: add blue and violet noise by using spectral inversion
authorStefan Kost <ensonic@users.sf.net>
Wed, 25 May 2011 21:17:40 +0000 (00:17 +0300)
committerStefan Kost <ensonic@users.sf.net>
Wed, 25 May 2011 21:18:55 +0000 (00:18 +0300)
Add blue and violet noise by spectral inversion of pink and red noise.
Fixes #649969

gst/audiotestsrc/gstaudiotestsrc.c
gst/audiotestsrc/gstaudiotestsrc.h

index 1570c59..030322e 100644 (file)
@@ -131,6 +131,8 @@ gst_audiostestsrc_wave_get_type (void)
     {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"},
+    {GST_AUDIO_TEST_SRC_WAVE_BLUE_NOISE, "Blue noise", "blue-noise"},
+    {GST_AUDIO_TEST_SRC_WAVE_VIOLET_NOISE, "Violet noise", "violet-noise"},
     {0, NULL, NULL},
   };
 
@@ -879,6 +881,66 @@ static const ProcessFunc red_noise_funcs[] = {
   (ProcessFunc) gst_audio_test_src_create_red_noise_double
 };
 
+/* Blue Noise: apply spectral inversion to pink noise */
+
+#define DEFINE_BLUE_NOISE(type) \
+static void \
+gst_audio_test_src_create_blue_noise_##type (GstAudioTestSrc * src, g##type * samples) \
+{ \
+  gint i, c; \
+  static gdouble flip=1.0; \
+  \
+  gst_audio_test_src_create_pink_noise_##type (src, samples); \
+  for (i = 0; i < src->generate_samples_per_buffer * src->channels; ) { \
+    for (c = 0; c < src->channels; ++c) { \
+      samples[i++] *= flip; \
+    } \
+    flip *= -1.0; \
+  } \
+}
+
+DEFINE_BLUE_NOISE (int16);
+DEFINE_BLUE_NOISE (int32);
+DEFINE_BLUE_NOISE (float);
+DEFINE_BLUE_NOISE (double);
+
+static const ProcessFunc blue_noise_funcs[] = {
+  (ProcessFunc) gst_audio_test_src_create_blue_noise_int16,
+  (ProcessFunc) gst_audio_test_src_create_blue_noise_int32,
+  (ProcessFunc) gst_audio_test_src_create_blue_noise_float,
+  (ProcessFunc) gst_audio_test_src_create_blue_noise_double
+};
+
+
+/* Violet Noise: apply spectral inversion to red noise */
+
+#define DEFINE_VIOLET_NOISE(type) \
+static void \
+gst_audio_test_src_create_violet_noise_##type (GstAudioTestSrc * src, g##type * samples) \
+{ \
+  gint i, c; \
+  static gdouble flip=1.0; \
+  \
+  gst_audio_test_src_create_red_noise_##type (src, samples); \
+  for (i = 0; i < src->generate_samples_per_buffer * src->channels; ) { \
+    for (c = 0; c < src->channels; ++c) { \
+      samples[i++] *= flip; \
+    } \
+    flip *= -1.0; \
+  } \
+}
+
+DEFINE_VIOLET_NOISE (int16);
+DEFINE_VIOLET_NOISE (int32);
+DEFINE_VIOLET_NOISE (float);
+DEFINE_VIOLET_NOISE (double);
+
+static const ProcessFunc violet_noise_funcs[] = {
+  (ProcessFunc) gst_audio_test_src_create_violet_noise_int16,
+  (ProcessFunc) gst_audio_test_src_create_violet_noise_int32,
+  (ProcessFunc) gst_audio_test_src_create_violet_noise_float,
+  (ProcessFunc) gst_audio_test_src_create_violet_noise_double
+};
 
 
 /*
@@ -939,6 +1001,17 @@ gst_audio_test_src_change_wave (GstAudioTestSrc * src)
       src->red.state = 0.0;
       src->process = red_noise_funcs[src->format];
       break;
+    case GST_AUDIO_TEST_SRC_WAVE_BLUE_NOISE:
+      if (!(src->gen))
+        src->gen = g_rand_new ();
+      gst_audio_test_src_init_pink_noise (src);
+      src->process = blue_noise_funcs[src->format];
+      break;
+    case GST_AUDIO_TEST_SRC_WAVE_VIOLET_NOISE:
+      if (!(src->gen))
+        src->gen = g_rand_new ();
+      src->red.state = 0.0;
+      src->process = violet_noise_funcs[src->format];
     default:
       GST_ERROR ("invalid wave-form");
       break;
index 971fe77..529ad63 100644 (file)
@@ -65,7 +65,9 @@ typedef enum {
   GST_AUDIO_TEST_SRC_WAVE_SINE_TAB,
   GST_AUDIO_TEST_SRC_WAVE_TICKS,
   GST_AUDIO_TEST_SRC_WAVE_GAUSSIAN_WHITE_NOISE,
-  GST_AUDIO_TEST_SRC_WAVE_RED_NOISE
+  GST_AUDIO_TEST_SRC_WAVE_RED_NOISE,
+  GST_AUDIO_TEST_SRC_WAVE_BLUE_NOISE,
+  GST_AUDIO_TEST_SRC_WAVE_VIOLET_NOISE
 } GstAudioTestSrcWave;
 
 #define PINK_MAX_RANDOM_ROWS   (30)