From 11590ac0b631e50ed6e7776ba918417b0011f752 Mon Sep 17 00:00:00 2001 From: Stefan Sauer Date: Wed, 30 Nov 2011 14:20:38 +0100 Subject: [PATCH] spacescope: add color-modes In colormode we split the signal in low,mid,high frequency parts and draw them separately into red, gree, blue color channels. --- gst/audiovisualizers/gstdrawhelpers.h | 9 +- gst/audiovisualizers/gstspacescope.c | 211 ++++++++++++++++++++++++-- gst/audiovisualizers/gstspacescope.h | 6 + 3 files changed, 212 insertions(+), 14 deletions(-) diff --git a/gst/audiovisualizers/gstdrawhelpers.h b/gst/audiovisualizers/gstdrawhelpers.h index 290713f347..815fae35e6 100644 --- a/gst/audiovisualizers/gstdrawhelpers.h +++ b/gst/audiovisualizers/gstdrawhelpers.h @@ -24,8 +24,12 @@ _vd[(_y * _st) + _x] = _c; \ } G_STMT_END +#define draw_dot_c(_vd, _x, _y, _st, _c) G_STMT_START { \ + _vd[(_y * _st) + _x] |= _c; \ +} G_STMT_END + #define draw_dot_aa(_vd, _x, _y, _st, _c, _f) G_STMT_START { \ - guint32 _oc, _nc, _c1, _c2, _c3; \ + guint32 _oc, _c1, _c2, _c3; \ \ _oc = _vd[(_y * _st) + _x]; \ _c3 = (_oc & 0xff) + ((_c & 0xff) * _f); \ @@ -34,8 +38,7 @@ _c2 = MIN(_c2, 255); \ _c1 = ((_oc & 0xff0000) >> 16) + (((_c & 0xff0000) >> 16) * _f); \ _c1 = MIN(_c1, 255); \ - _nc = (_c1 << 16) | (_c2 << 8) | _c3; \ - _vd[(_y * _st) + _x] = _nc; \ + _vd[(_y * _st) + _x] = (_c1 << 16) | (_c2 << 8) | _c3; \ } G_STMT_END #define draw_line(_vd, _x1, _x2, _y1, _y2, _st, _c) G_STMT_START { \ diff --git a/gst/audiovisualizers/gstspacescope.c b/gst/audiovisualizers/gstspacescope.c index 41f8bdb412..7fefd9a3b7 100644 --- a/gst/audiovisualizers/gstspacescope.c +++ b/gst/audiovisualizers/gstspacescope.c @@ -66,6 +66,8 @@ enum { STYLE_DOTS = 0, STYLE_LINES, + STYLE_COLOR_DOTS, + STYLE_COLOR_LINES, NUM_STYLES }; @@ -79,6 +81,8 @@ gst_space_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} }; @@ -92,9 +96,13 @@ static void gst_space_scope_set_property (GObject * object, guint prop_id, static void gst_space_scope_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); -static void render_dots (GstBaseAudioVisualizer * scope, guint32 * vdata, +static void render_dots (GstBaseAudioVisualizer * base, guint32 * vdata, gint16 * adata, guint num_samples); -static void render_lines (GstBaseAudioVisualizer * scope, guint32 * vdata, +static void render_lines (GstBaseAudioVisualizer * base, 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_space_scope_render (GstBaseAudioVisualizer * scope, @@ -160,6 +168,12 @@ gst_space_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 +201,19 @@ gst_space_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) { guint i, s, x, y, ox, oy; gfloat dx, dy; - guint w = scope->width; + guint w = base->width; + guint h = base->height; /* draw dots 1st channel x, 2nd channel y */ - dx = scope->width / 65536.0; - ox = scope->width / 2; - dy = scope->height / 65536.0; - oy = scope->height / 2; + dx = w / 65536.0; + ox = w / 2; + dy = h / 65536.0; + oy = h / 2; s = 0; for (i = 0; i < num_samples; i++) { x = (guint) (ox + (gfloat) adata[s++] * dx); @@ -208,13 +223,13 @@ 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) { guint i, s, x, y, ox, 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 1st channel x, 2nd channel y */ @@ -234,6 +249,180 @@ 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(il, ir) G_STMT_START { \ + f1l_h = il - (f1l_m * RESONANCE) - f1l_l; \ + f1l_m += (f1l_h * CUTOFF_1); \ + f1l_l += (f1l_m * CUTOFF_1); \ + \ + f2l_h = (f1l_m + f1l_h) - (f2l_m * RESONANCE) - f2l_l; \ + f2l_m += (f2l_h * CUTOFF_2); \ + f2l_l += (f2l_m * CUTOFF_2); \ + \ + f1r_h = ir - (f1r_m * RESONANCE) - f1r_l; \ + f1r_m += (f1r_h * CUTOFF_1); \ + f1r_l += (f1r_m * CUTOFF_1); \ + \ + f2r_h = (f1r_m + f1r_h) - (f2r_m * RESONANCE) - f2r_l; \ + f2r_m += (f2r_h * CUTOFF_2); \ + f2r_l += (f2r_m * CUTOFF_2); \ +} G_STMT_END + + +static void +render_color_dots (GstBaseAudioVisualizer * base, guint32 * vdata, + gint16 * adata, guint num_samples) +{ + GstSpaceScope *scope = (GstSpaceScope *) base; + guint i, s; + gint x, y, ox, oy; + gfloat dx, dy; + gint w = base->width, w1 = w - 2; + gint h = base->height, h1 = h - 2; + gdouble il, ir; + gdouble f1l_l = scope->f1l_l, f1l_m = scope->f1l_m, f1l_h = scope->f1l_h; + gdouble f1r_l = scope->f1r_l, f1r_m = scope->f1r_m, f1r_h = scope->f1r_h; + gdouble f2l_l = scope->f2l_l, f2l_m = scope->f2l_m, f2l_h = scope->f2l_h; + gdouble f2r_l = scope->f2r_l, f2r_m = scope->f2r_m, f2r_h = scope->f2r_h; + + /* draw dots 1st channel x, 2nd channel y */ + ox = w / 2; + oy = h / 2; + dx = w / 65536.0; + dy = h / 65536.0; + s = 0; + for (i = 0; i < num_samples; i++) { + il = (gdouble) adata[s++]; + ir = (gdouble) adata[s++]; + + filter (il, ir); + + x = (gint) (ox + f1l_l * dx); + y = (gint) (oy + f1r_l * dy); + x = CLAMP (x, 0, w1); + y = CLAMP (y, 0, h1); + draw_dot_c (vdata, x, y, w, 0x00FF0000); + + x = (gint) (ox + f2l_l * dx); + y = (gint) (oy + f2r_l * dy); + x = CLAMP (x, 0, w1); + y = CLAMP (y, 0, h1); + draw_dot_c (vdata, x, y, w, 0x0000FF00); + + x = (gint) (ox + (f2l_m + f2l_h) * dx); + y = (gint) (oy + (f2r_m + f2r_h) * dy); + x = CLAMP (x, 0, w1); + y = CLAMP (y, 0, h1); + draw_dot_c (vdata, x, y, w, 0x000000FF); + } + + scope->f1l_l = f1l_l; + scope->f1l_m = f1l_m; + scope->f1l_h = f1l_h; + scope->f1r_l = f1r_l; + scope->f1r_m = f1r_m; + scope->f1r_h = f1r_h; + scope->f2l_l = f2l_l; + scope->f2l_m = f2l_m; + scope->f2l_h = f2l_h; + scope->f2r_l = f2r_l; + scope->f2r_m = f2r_m; + scope->f2r_h = f2r_h; +} + +static void +render_color_lines (GstBaseAudioVisualizer * base, guint32 * vdata, + gint16 * adata, guint num_samples) +{ + GstSpaceScope *scope = (GstSpaceScope *) base; + guint i, s; + gint x, y, ox, oy; + gfloat dx, dy; + gint w = base->width, w1 = w - 2; + gint h = base->height, h1 = h - 2; + gdouble il, ir; + gdouble f1l_l = scope->f1l_l, f1l_m = scope->f1l_m, f1l_h = scope->f1l_h; + gdouble f1r_l = scope->f1r_l, f1r_m = scope->f1r_m, f1r_h = scope->f1r_h; + gdouble f2l_l = scope->f2l_l, f2l_m = scope->f2l_m, f2l_h = scope->f2l_h; + gdouble f2r_l = scope->f2r_l, f2r_m = scope->f2r_m, f2r_h = scope->f2r_h; + gint x2, y2, x3, y3, x4, y4; + + /* draw lines 1st channel x, 2nd channel y */ + ox = w / 2; + oy = h / 2; + dx = w / 65536.0; + dy = h / 65536.0; + s = 0; + + /* do first pixels */ + il = (gdouble) adata[s++]; + ir = (gdouble) adata[s++]; + + filter (il, ir); + + x = (gint) (ox + f1l_l * dx); + y = (gint) (oy + f1r_l * dy); + x2 = CLAMP (x, 0, w1); + y2 = CLAMP (y, 0, h1); + + x = (gint) (ox + f2l_l * dx); + y = (gint) (oy + f2r_l * dy); + x3 = CLAMP (x, 0, w1); + y3 = CLAMP (y, 0, h1); + + x = (gint) (ox + (f2l_m + f2l_h) * dx); + y = (gint) (oy + (f2r_m + f2r_h) * dy); + x4 = CLAMP (x, 0, w1); + y4 = CLAMP (y, 0, h1); + + for (i = 1; i < num_samples; i++) { + il = (gdouble) adata[s++]; + ir = (gdouble) adata[s++]; + + filter (il, ir); + + x = (gint) (ox + f1l_l * dx); + y = (gint) (oy + f1r_l * dy); + x = CLAMP (x, 0, w1); + y = CLAMP (y, 0, h1); + draw_line_aa (vdata, x2, x, y2, y, w, 0x00FF0000); + x2 = x; + y2 = y; + + x = (gint) (ox + f2l_l * dx); + y = (gint) (oy + f2r_l * dy); + x = CLAMP (x, 0, w1); + y = CLAMP (y, 0, h1); + draw_line_aa (vdata, x3, x, y3, y, w, 0x0000FF00); + x3 = x; + y3 = y; + + x = (gint) (ox + (f2l_m + f2l_h) * dx); + y = (gint) (oy + (f2r_m + f2r_h) * dy); + x = CLAMP (x, 0, w1); + y = CLAMP (y, 0, h1); + draw_line_aa (vdata, x4, x, y4, y, w, 0x000000FF); + x4 = x; + y4 = y; + } + + scope->f1l_l = f1l_l; + scope->f1l_m = f1l_m; + scope->f1l_h = f1l_h; + scope->f1r_l = f1r_l; + scope->f1r_m = f1r_m; + scope->f1r_h = f1r_h; + scope->f2l_l = f2l_l; + scope->f2l_m = f2l_m; + scope->f2l_h = f2l_h; + scope->f2r_l = f2r_l; + scope->f2r_m = f2r_m; + scope->f2r_h = f2r_h; +} + static gboolean gst_space_scope_render (GstBaseAudioVisualizer * base, GstBuffer * audio, GstBuffer * video) diff --git a/gst/audiovisualizers/gstspacescope.h b/gst/audiovisualizers/gstspacescope.h index 62600f4b4b..165455e294 100644 --- a/gst/audiovisualizers/gstspacescope.h +++ b/gst/audiovisualizers/gstspacescope.h @@ -42,6 +42,12 @@ struct _GstSpaceScope /* < private > */ GstSpaceScopeProcessFunc process; gint style; + + /* filter specific data */ + gdouble f1l_l, f1l_m, f1l_h; + gdouble f1r_l, f1r_m, f1r_h; + gdouble f2l_l, f2l_m, f2l_h; + gdouble f2r_l, f2r_m, f2r_h; }; struct _GstSpaceScopeClass -- 2.34.1