{
STYLE_DOTS = 0,
STYLE_LINES,
+ STYLE_COLOR_DOTS,
+ STYLE_COLOR_LINES,
NUM_STYLES
};
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}
};
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);
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,
}
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)
{
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:
#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++) {
}
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 */
}
}
+#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)