wavescape: also add colormodes like in spacescope
authorStefan Sauer <ensonic@users.sf.net>
Wed, 30 Nov 2011 21:11:40 +0000 (22:11 +0100)
committerStefan Sauer <ensonic@users.sf.net>
Wed, 30 Nov 2011 21:11:40 +0000 (22:11 +0100)
gst/audiovisualizers/gstwavescope.c
gst/audiovisualizers/gstwavescope.h

index 71468ae..a2ee51f 100644 (file)
@@ -66,6 +66,8 @@ enum
 {
   STYLE_DOTS = 0,
   STYLE_LINES,
+  STYLE_COLOR_DOTS,
+  STYLE_COLOR_LINES,
   NUM_STYLES
 };
 
@@ -79,6 +81,8 @@ gst_wave_scope_style_get_type (void)
     static const GEnumValue values[] = {
       {STYLE_DOTS, "draw dots (default)", "dots"},
       {STYLE_LINES, "draw lines", "lines"},
+      {STYLE_COLOR_DOTS, "draw color dots", "color-dots"},
+      {STYLE_COLOR_LINES, "draw color lines", "color-lines"},
       {0, NULL, NULL}
     };
 
@@ -91,12 +95,18 @@ static void gst_wave_scope_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec);
 static void gst_wave_scope_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec);
+static void gst_wave_scope_finalize (GObject * object);
 
 static void render_dots (GstBaseAudioVisualizer * scope, guint32 * vdata,
     gint16 * adata, guint num_samples);
 static void render_lines (GstBaseAudioVisualizer * scope, guint32 * vdata,
     gint16 * adata, guint num_samples);
+static void render_color_dots (GstBaseAudioVisualizer * base, guint32 * vdata,
+    gint16 * adata, guint num_samples);
+static void render_color_lines (GstBaseAudioVisualizer * base, guint32 * vdata,
+    gint16 * adata, guint num_samples);
 
+static gboolean gst_wave_scope_setup (GstBaseAudioVisualizer * scope);
 static gboolean gst_wave_scope_render (GstBaseAudioVisualizer * base,
     GstBuffer * audio, GstBuffer * video);
 
@@ -128,7 +138,9 @@ gst_wave_scope_class_init (GstWaveScopeClass * g_class)
 
   gobject_class->set_property = gst_wave_scope_set_property;
   gobject_class->get_property = gst_wave_scope_get_property;
+  gobject_class->finalize = gst_wave_scope_finalize;
 
+  scope_class->setup = GST_DEBUG_FUNCPTR (gst_wave_scope_setup);
   scope_class->render = GST_DEBUG_FUNCPTR (gst_wave_scope_render);
 
   g_object_class_install_property (gobject_class, PROP_STYLE,
@@ -145,6 +157,32 @@ gst_wave_scope_init (GstWaveScope * scope, GstWaveScopeClass * g_class)
 }
 
 static void
+gst_wave_scope_finalize (GObject * object)
+{
+  GstWaveScope *scope = GST_WAVE_SCOPE (object);
+
+  if (scope->flt) {
+    g_free (scope->flt);
+    scope->flt = NULL;
+  }
+
+  G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static gboolean
+gst_wave_scope_setup (GstBaseAudioVisualizer * bscope)
+{
+  GstWaveScope *scope = GST_WAVE_SCOPE (bscope);
+
+  if (scope->flt)
+    g_free (scope->flt);
+
+  scope->flt = g_new0 (gdouble, 6 * bscope->channels);
+
+  return TRUE;
+}
+
+static void
 gst_wave_scope_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec)
 {
@@ -160,6 +198,12 @@ gst_wave_scope_set_property (GObject * object, guint prop_id,
         case STYLE_LINES:
           scope->process = render_lines;
           break;
+        case STYLE_COLOR_DOTS:
+          scope->process = render_color_dots;
+          break;
+        case STYLE_COLOR_LINES:
+          scope->process = render_color_lines;
+          break;
       }
       break;
     default:
@@ -187,18 +231,19 @@ gst_wave_scope_get_property (GObject * object, guint prop_id,
 #include "gstdrawhelpers.h"
 
 static void
-render_dots (GstBaseAudioVisualizer * scope, guint32 * vdata, gint16 * adata,
+render_dots (GstBaseAudioVisualizer * base, guint32 * vdata, gint16 * adata,
     guint num_samples)
 {
-  gint channels = scope->channels;
+  gint channels = base->channels;
   guint i, c, s, x, y, oy;
   gfloat dx, dy;
-  guint w = scope->width;
+  guint w = base->width;
+  guint h = base->height;
 
   /* draw dots */
   dx = (gfloat) w / (gfloat) num_samples;
-  dy = scope->height / 65536.0;
-  oy = scope->height / 2;
+  dy = h / 65536.0;
+  oy = h / 2;
   for (c = 0; c < channels; c++) {
     s = c;
     for (i = 0; i < num_samples; i++) {
@@ -211,14 +256,14 @@ render_dots (GstBaseAudioVisualizer * scope, guint32 * vdata, gint16 * adata,
 }
 
 static void
-render_lines (GstBaseAudioVisualizer * scope, guint32 * vdata, gint16 * adata,
+render_lines (GstBaseAudioVisualizer * base, guint32 * vdata, gint16 * adata,
     guint num_samples)
 {
-  gint channels = scope->channels;
+  gint channels = base->channels;
   guint i, c, s, x, y, oy;
   gfloat dx, dy;
-  guint w = scope->width;
-  guint h = scope->height;
+  guint w = base->width;
+  guint h = base->height;
   gint x2, y2;
 
   /* draw lines */
@@ -240,6 +285,119 @@ render_lines (GstBaseAudioVisualizer * scope, guint32 * vdata, gint16 * adata,
   }
 }
 
+#define CUTOFF_1 0.15
+#define CUTOFF_2 0.45
+#define RESONANCE (1.0/0.5)
+
+#define filter(in) G_STMT_START {                                              \
+  flt[2] = in - (flt[1] * RESONANCE) - flt[0];                                 \
+  flt[1] += (flt[2] * CUTOFF_1);                                               \
+  flt[0] += (flt[1] * CUTOFF_1);                                               \
+                                                                               \
+  flt[5] = (flt[1] + flt[2]) - (flt[4] * RESONANCE) - flt[3];                  \
+  flt[4] += (flt[5] * CUTOFF_2);                                               \
+  flt[3] += (flt[4] * CUTOFF_2);                                               \
+} G_STMT_END
+
+static void
+render_color_dots (GstBaseAudioVisualizer * base, guint32 * vdata,
+    gint16 * adata, guint num_samples)
+{
+  GstWaveScope *scope = (GstWaveScope *) base;
+  gint channels = base->channels;
+  guint i, c, s, x, y, oy;
+  gfloat dx, dy;
+  guint w = base->width;
+  guint h = base->height, h1 = h - 2;
+  gdouble *flt = scope->flt;
+
+  /* draw dots */
+  dx = (gfloat) w / (gfloat) num_samples;
+  dy = h / 65536.0;
+  oy = h / 2;
+  for (c = 0; c < channels; c++) {
+    s = c;
+    for (i = 0; i < num_samples; i++) {
+      x = (guint) ((gfloat) i * dx);
+      filter ((gfloat) adata[s]);
+
+      y = (guint) (oy + flt[0] * dy);
+      y = CLAMP (y, 0, h1);
+      draw_dot_c (vdata, x, y, w, 0x00FF0000);
+
+      y = (guint) (oy + flt[3] * dy);
+      y = CLAMP (y, 0, h1);
+      draw_dot_c (vdata, x, y, w, 0x0000FF00);
+
+      y = (guint) (oy + (flt[4] + flt[5]) * dy);
+      y = CLAMP (y, 0, h1);
+      draw_dot_c (vdata, x, y, w, 0x000000FF);
+
+      s += channels;
+    }
+    flt += 6;
+  }
+}
+
+static void
+render_color_lines (GstBaseAudioVisualizer * base, guint32 * vdata,
+    gint16 * adata, guint num_samples)
+{
+  GstWaveScope *scope = (GstWaveScope *) base;
+  gint channels = base->channels;
+  guint i, c, s, x, y, oy;
+  gfloat dx, dy;
+  guint w = base->width;
+  guint h = base->height, h1 = h - 2;
+  gdouble *flt = scope->flt;
+  gint x2, y2, y3, y4;
+
+  /* draw lines */
+  dx = (gfloat) (w - 1) / (gfloat) num_samples;
+  dy = (h - 1) / 65536.0;
+  oy = (h - 1) / 2;
+  for (c = 0; c < channels; c++) {
+    s = c;
+
+    /* do first pixels */
+    x2 = 0;
+    filter ((gfloat) adata[s]);
+
+    y = (guint) (oy + flt[0] * dy);
+    y2 = CLAMP (y, 0, h1);
+
+    y = (guint) (oy + flt[3] * dy);
+    y3 = CLAMP (y, 0, h1);
+
+    y = (guint) (oy + (flt[4] + flt[5]) * dy);
+    y4 = CLAMP (y, 0, h1);
+
+    for (i = 1; i < num_samples; i++) {
+      x = (guint) ((gfloat) i * dx);
+      filter ((gfloat) adata[s]);
+
+      y = (guint) (oy + flt[0] * dy);
+      y = CLAMP (y, 0, h1);
+      draw_line_aa (vdata, x2, x, y2, y, w, 0x00FF0000);
+      y2 = y;
+
+      y = (guint) (oy + flt[3] * dy);
+      y = CLAMP (y, 0, h1);
+      draw_line_aa (vdata, x2, x, y3, y, w, 0x0000FF00);
+      y3 = y;
+
+      y = (guint) (oy + (flt[4] + flt[5]) * dy);
+      y = CLAMP (y, 0, h1);
+      draw_line_aa (vdata, x2, x, y4, y, w, 0x000000FF);
+      y4 = y;
+
+      x2 = x;
+      s += channels;
+    }
+    flt += 6;
+  }
+}
+
 static gboolean
 gst_wave_scope_render (GstBaseAudioVisualizer * base, GstBuffer * audio,
     GstBuffer * video)
index ffe3411..42137f7 100644 (file)
@@ -42,6 +42,9 @@ struct _GstWaveScope
   /* < private > */
   GstWaveScopeProcessFunc process;
   gint style;
+
+  /* filter specific data */
+  gdouble *flt;
 };
 
 struct _GstWaveScopeClass