diff options
author | 2010-04-07 19:51:33 +0200 | |
---|---|---|
committer | 2010-04-07 19:55:46 +0200 | |
commit | b23a226ecaff0f59eb87678c1b9b692b0b0ddc5b (patch) | |
tree | 0b4db3282ed97e965323bf56fc113eedd69efcea /plugins/gtkui/ddbequalizer.vala | |
parent | 2bacca9c18ae6440205909c6f081e85b22be1e39 (diff) |
stripped down version of new eq widget;
fixed saving/loading eq settings;
added preamp support in supereq plugin
Diffstat (limited to 'plugins/gtkui/ddbequalizer.vala')
-rw-r--r-- | plugins/gtkui/ddbequalizer.vala | 540 |
1 files changed, 57 insertions, 483 deletions
diff --git a/plugins/gtkui/ddbequalizer.vala b/plugins/gtkui/ddbequalizer.vala index c861ce96..adf10c71 100644 --- a/plugins/gtkui/ddbequalizer.vala +++ b/plugins/gtkui/ddbequalizer.vala @@ -1,6 +1,3 @@ -static const int spot_size = 3; -static const int bands = 18; - const string[] freqs = { "55 Hz","77 Hz","110 Hz","156 Hz","220 Hz","311 Hz","440 Hz","622 Hz","880 Hz", "1.2 kHz","1.8 kHz","2.5 kHz","3.5 kHz","5 kHz","7 kHz","10 kHz","14 kHz","20 kHz" @@ -9,40 +6,25 @@ const string[] freqs = { namespace Ddb { public class Equalizer : Gtk.DrawingArea { - public signal void on_changed (double[] values); - - class Point - { - public double x; - public double y; - } - - private List <Point> points = new List <Point> (); - private unowned List <Point> current_point = null; - -// private Gdk.Color back_color; -// private Gdk.Color fore_bright_color; -// private Gdk.Color fore_dark_color; + public signal void on_changed (); private double[] values = new double [bands]; - private double preamp; + private double preamp = 0.5; private int mouse_y; - private bool snap = false; private bool aa_mode = false; - private bool draw_envelope = false; private bool curve_hook = false; private bool preamp_hook = false; - private Gtk.Menu menu = null; - private int margin_bottom = -1; private int margin_left = -1; + static const int spot_size = 3; + static const int bands = 18; - Gdk.Cursor moving_cursor = new Gdk.Cursor (Gdk.CursorType.FLEUR); -// Gdk.Cursor updown_cursor = new Gdk.Cursor (Gdk.CursorType.DOUBLE_ARROW); +// Gdk.Cursor moving_cursor = new Gdk.Cursor (Gdk.CursorType.FLEUR); +// Gdk.Cursor updown_cursor = new Gdk.Cursor (Gdk.CursorType.double_ARROW); Gdk.Cursor pointer_cursor = new Gdk.Cursor (Gdk.CursorType.LEFT_PTR); construct @@ -54,39 +36,9 @@ namespace Ddb { modify_bg (Gtk.StateType.NORMAL, get_style ().fg[Gtk.StateType.NORMAL]); - recalc_values(); margin_bottom = (int)(Pango.units_to_double (get_style ().font_desc.get_size ())* Gdk.Screen.get_default ().get_resolution () / 72 + 4); margin_left = margin_bottom * 4; - preamp = 0.5; - - set_snap (true); - - menu = new Gtk.Menu (); - var checkitem = new Gtk.CheckMenuItem.with_label ("Antialiasing"); - checkitem.show(); - checkitem.toggled.connect (aa_mode_changed); - menu.append (checkitem); - - var mode_item = new Gtk.MenuItem(); - mode_item.show (); - mode_item.label = "mode"; - menu.append (mode_item); - - var mode_menu = new Gtk.Menu (); - - var group = new GLib.SList <Gtk.RadioMenuItem> (); - - var thesame_item = new Gtk.RadioMenuItem.with_label (group, "thesame"); - thesame_item.show(); - mode_menu.append (thesame_item); - - var waker_item = new Gtk.RadioMenuItem.with_label_from_widget (thesame_item, "waker"); - waker_item.show(); - waker_item.toggled.connect (mode_changed); - mode_menu.append (waker_item); - - mode_item.set_submenu (mode_menu); } public void @@ -96,99 +48,14 @@ namespace Ddb { queue_draw (); } - public void - mode_changed (Gtk.CheckMenuItem item) - { - set_snap (item.active); - } - - private void - set_snap (bool new_snap) - { - snap = new_snap; - - if (snap) - { - double step = 1.0 / (double)(bands+1); - - if (points.length() > 0) - { - unowned List <Point> iter; - for (iter = points.next; iter != null; iter = iter.next) - points.remove_link (iter.prev); - points.remove_link (points); - } - - for (int i = 0; i < bands; i++) - { - Point point = new Point (); - point.x = ((double)i+1)*step; - point.y = values[i]; - points.prepend (point); - } - points.reverse (); - } - } - - private Gdk.Point - abs_to_screen (double x, double y) - { - return Gdk.Point () { - x = (int)(x * (this.allocation.width-margin_left))+margin_left, - y = (int)(y * (this.allocation.height-margin_bottom)) - }; - } - - private void - abs_to_screen_d (double x, double y, out double sx, out double sy) - { - sx = (int)(x * (this.allocation.width-margin_left))+margin_left; - sy = (int)(y * (this.allocation.height-margin_bottom)); - } - -/* private double - cubic (double y0, double y1, double y2, double y3, double mu) - { - double a0,a1,a2,a3,mu2; - - mu2 = mu*mu; - a0 = y3 - y2 - y0 + y1; - a1 = y0 - y1 - a0; - a2 = y2 - y0; - a3 = y1; - - return (a0*mu*mu2+a1*mu2+a2*mu+a3); - }*/ - - private double - cubic (double y0, double y1, double y2, double y3, double mu) - { - return 0.5 *((2 * y1) + - (-y0 + y2) * mu + - (2*y0 - 5*y1 + 4*y2 - y3) * mu*mu + - (-y0 + 3*y1- 3*y2 + y3) * mu*mu*mu); - } - public override bool expose_event (Gdk.EventExpose event) { Gdk.Color fore_bright_color = Gtkui.get_bar_foreground_color (); Gdk.Color fore_dark_color = Gtkui.get_bar_foreground_color (); - int width = this.allocation.width; - int height = this.allocation.height; - - Gdk.Point[] gpoints = new Gdk.Point [points.length()+2]; - gpoints[0] = {margin_left, (height-margin_bottom) / 2}; - int i = 1; - foreach (var p in this.points) - { - gpoints[i] = abs_to_screen (p.x, p.y); - if (gpoints[i].x >= width) - gpoints[i].x = width - 1; - i++; - } - gpoints[i] = {width-1, (height-margin_bottom) / 2}; + int width = allocation.width; + int height = allocation.height; Gdk.Drawable d = get_window(); var gc = d.create_gc (Gdk.GCValues(), 0); @@ -196,6 +63,7 @@ namespace Ddb { gc.set_rgb_fg_color (fore_dark_color); //drawing grid: double step = (double)(width - margin_left) / (double)(bands+1); + int i; for (i = 0; i < bands; i++) { //does anyone know why this method is static? @@ -206,7 +74,6 @@ namespace Ddb { height - margin_bottom); } - //double vstep = 1.0 / (double)(height-margin_bottom); double vstep = (double)(height-margin_bottom); for (double di=0; di < 2; di += 0.25) { @@ -306,328 +173,52 @@ namespace Ddb { } gc.set_clip_rectangle ({0, 0, width, height}); - if (draw_envelope) { - //drawing curve: - gc.set_rgb_fg_color (fore_bright_color); - Gdk.Point gp; - uint pcount = points.length(); - double[] ys = new double [pcount]; - double[] xs = new double [pcount]; - i=0; - foreach (var p in this.points) - { - gp = abs_to_screen (p.x, p.y); - d.draw_rectangle (gc, true, gp.x-spot_size, gp.y-spot_size, spot_size*2, spot_size*2); - xs[i] = p.x; - ys[i] = p.y; - i++; - } - - Cairo.Context cairo = aa_mode ? Gdk.cairo_create (d) : null; - - int prev_x = 0; - int prev_y = 0; - - if (pcount > 0) - { - gp = abs_to_screen (xs[0], ys[0]); - if (aa_mode) - cairo.move_to (margin_left, gp.y); - else - Gdk.draw_line (d, gc, margin_left, gp.y, gp.x, gp.y); - prev_x = gp.x; - prev_y = gp.y; - } - - if (pcount >= 2) - { - for (i = 0; i < pcount-1; i++) - { - //stdout.printf ("%d\n", (int)((xs[i+1]-xs[i])*width)); - if ((int)((xs[i+1]-xs[i])*width) <= 5) - { - Gdk.Point gp2 = abs_to_screen (xs[i], ys[i]); - gp = abs_to_screen (xs[i+1], ys[i+1]); - Gdk.draw_line (d, gc, gp2.x, gp2.y, gp.x, gp.y); - prev_x = gp2.x; - prev_y = gp2.y; - continue; - } - //int pts = (int)((double)((xs[i+1] - xs[i]) * allocation.width) / 5.0); - //step = (double)(xs[i+1] - xs[i])/(double)pts; - - double dx = (xs[i+1] - xs[i])*width; - double dy = (ys[i+1] - ys[i])*height; - int pts = (int)(GLib.Math.sqrt (dx*dx + dy*dy) / 5.0); - //stdout.printf ("%f %f %d\n", dx, dy, pts); - step = (double)(xs[i+1] - xs[i])/(double)pts; - - for (int ii = 0; ii <= pts; ii++) - { - double y; - - if (i == 0 && i == pcount-2) //case when we have only two points - y = cubic (ys[0], ys[0], ys[1], ys[1], (double)ii/(double)pts); - - else if (i == 0) - y = cubic (ys[0], ys[0], ys[1], ys[2], (double)ii/(double)pts); - - else if (i == pcount-2) - y = cubic (ys[i-1], ys[i], ys[i+1], ys[i+1], (double)ii/(double)pts); - - else - y = cubic (ys[i-1], ys[i], ys[i+1], ys[i+2], (double)ii/(double)pts); - if (y < 0) y = 0; - if (y > 1) y = 1; - - if (aa_mode) - { - double sx, sy; - abs_to_screen_d (ii*step+xs[i], y, out sx, out sy); - cairo.line_to (sx, sy); - // prev_x = gp.x; - // prev_y = gp.y; - } - else - { - gp = abs_to_screen (ii*step+xs[i], y); - - if (gp.y < 2) gp.y = 2; - if (gp.y > height-margin_bottom-2) gp.y = height-margin_bottom-2; - - Gdk.draw_point (d, gc, gp.x, gp.y); - //Gdk.draw_line (d, gc, prev_x, prev_y, gp.x, gp.y); - prev_x = gp.x; - prev_y = gp.y; - } - } - } - } - if (pcount > 0) - { - // gp = abs_to_screen (xs[0], ys[0]); - // cairo.move_to (margin_left, gp.y); - // Gdk.draw_line (d, gc, margin_left, gp.y, gp.x, gp.y); - - gp = abs_to_screen (xs[pcount-1], ys[pcount-1]); - if (aa_mode) - cairo.line_to (width-1, gp.y); - else - Gdk.draw_line (d, gc, gp.x, gp.y, width-1, gp.y); - } - if (aa_mode) - { - cairo.set_source_rgb ( - (double)fore_bright_color.red / (double)0xffff, - (double)fore_bright_color.green / (double)0xffff, - (double)fore_bright_color.blue / (double)0xffff); - cairo.stroke(); - } - if (pcount == 0) - { - Gdk.draw_line (d, gc, margin_left, (height-margin_bottom)/2, width-1, (height-margin_bottom)/2); - } - } - //drawing mouse coordinates: gc.set_line_attributes (1, Gdk.LineStyle.ON_OFF_DASH, Gdk.CapStyle.NOT_LAST, Gdk.JoinStyle.MITER); Gdk.draw_line (d, gc, margin_left+1, mouse_y, width, mouse_y); return false; } - - //FIXME: I'm not sure returning value thru instance property is good - private bool - get_point_at (double x, double y) - { - bool ret = false; - - unowned List <Point> iter; - - double ss_x = (double)spot_size / (double)allocation.width; - double ss_y = (double)spot_size / (double)allocation.height; - - for (iter = points; iter != null; iter = iter.next) - { - if (GLib.Math.fabs (iter.data.x - x) <= ss_x && - GLib.Math.fabs (iter.data.y - y) <= ss_y) - { - current_point = iter; - ret = true; - break; - } - } - return ret; - } - + private inline double scale (double val) { double k = -40; double d = 20; - return (val+preamp-0.5) * k + d; + return (val + preamp - 0.5) * k + d; } - private void - recalc_values () + private bool + in_curve_area (double x, double y) { - uint pcount = points.length(); - double[] ys = new double [pcount]; - double[] xs = new double [pcount]; - int i=0; - foreach (var p in this.points) - { - xs[i] = p.x; - ys[i] = p.y; - i++; - } - - if (pcount == 0) - { - for (i=0; i < bands; i++) - values[i] = 0.5; - } - else if (pcount == 1) - { - for (i=0; i < bands; i++) - values[i] = ys[0]; - } - else - { - int pi = 0; - for (i = 0; i < bands; i++) - { - double x = (double)(i+1)/(double)(bands+1); - double y = 0; - - if (xs[pi] > x) //before first point - { - values[i] = ys[pi]; - continue; - } - - if ((xs[pi+1] < x) && (pi < pcount-1)) //passed to next point - pi++; - - if (pi == pcount-1) //after last point - { - values[i] = ys[pcount-1]; - continue; - } - - if (pi == 0 && pi == pcount-2) //two-points case - y = cubic (ys[pi], ys[pi], ys[pi+1], ys[pi+1], - (x - xs[pi])/(xs[pi+1] - xs[pi])); - - else if (pi == 0) - y = cubic (ys[pi], ys[pi], ys[pi+1], ys[pi+2], - (x - xs[pi])/(xs[pi+1] - xs[pi])); - - else if (pi == pcount-2) - y = cubic (ys[pi-1], ys[pi], ys[pi+1], ys[pi+1], - (x - xs[pi])/(xs[pi+1] - xs[pi])); - - else - y = cubic (ys[pi-1], ys[pi], ys[pi+1], ys[pi+2], - (x - xs[pi])/(xs[pi+1] - xs[pi])); - if (y < 0) y = 0; - if (y > 1) y = 1; - values[i] = y; - } - } - double[] scaled_values = new double[bands]; - for (i = 0; i < bands; i++) - scaled_values[i] = scale (values[i]); - on_changed (scaled_values); + return + x > margin_left && + x < allocation.width-1 && + y > 1 && + y < allocation.height-margin_bottom; } private void - snap_move (double x, double y) - { - double step = 1.0 / (double)(bands+1); - int idx = (int)((x-step/2)/step); - if (idx < bands && idx >= 0) - { - current_point = points.nth (idx); - current_point.data.y = y; + update_eq_drag (double x, double y) { + double band_width = (double)(allocation.width - margin_left) / (double)(bands+1); + int band = (int)GLib.Math.floor ((x - margin_left) / band_width - 0.5); + if (band < 0) { + band = 0; } - } - - private void - handle_curve_click (Gdk.EventButton event) - { - double x = (double)(event.x - margin_left) / (double)(allocation.width - margin_left); - double y = event.y / (double)(allocation.height - margin_bottom); - - if (event.button == 1) - { - /* Handling left button: moving points */ - if (snap) - snap_move (x, y); - else - { - if (!get_point_at (x, y)) - { - var point = new Point(); - if (points == null) - { - points.append (point); - current_point = points; - } - else if (points.data.x > x) - { - points.prepend (point); - current_point = points; - } - else - { - var found = false; - for (unowned List <Point> i = points; i.next != null; i = i.next) - if (i.data.x < x && i.next.data.x > x) - { - points.insert_before (i.next, point); - current_point = i.next; - found = true; - break; - } - if (!found) - { - points.append (point); - current_point = points.last(); - } - } - } - current_point.data.x = x; - current_point.data.y = y; - } - recalc_values(); - get_window().set_cursor (moving_cursor); - queue_draw (); + if (band >= bands) { + band = band-1; } - else if (event.button == 3) - { - /* Handling right button: removing points */ - if (snap) - return; - if (get_point_at (x, y)) - { - points.remove (current_point.data); - recalc_values(); - queue_draw (); + if (band >= 0 && band < bands) { + values[band] = y / (double)(allocation.height - margin_bottom); + if (values[band] > 1) { + values[band] = 1; } - queue_draw(); + else if (values[band] < 0) { + values[band] = 0; + } + on_changed (); } } - - private bool - in_curve_area (int x, int y) - { - return - x > margin_left && - x < allocation.width-1 && - y > 1 && - y < allocation.height-margin_bottom; - } /* Mouse button got pressed over widget */ public override bool @@ -636,7 +227,7 @@ namespace Ddb { if (in_curve_area ((int)event.x, (int)event.y)) { curve_hook = true; - handle_curve_click (event); + update_eq_drag ((int)event.x, (int)event.y); return false; } @@ -647,14 +238,10 @@ namespace Ddb { ) { preamp = event.y / (double)(allocation.height - margin_bottom); + on_changed (); preamp_hook = true; } - if (event.button == 3) - { - //stdout.printf (""); - menu.popup (null, null, null, event.button, Gtk.get_current_event_time()); - } return false; } @@ -678,9 +265,7 @@ namespace Ddb { /* Mouse pointer moved over widget */ public override bool - motion_notify_event (Gdk.EventMotion event) - { - double x = (double)(event.x - margin_left) / (double)(allocation.width - margin_left); + motion_notify_event (Gdk.EventMotion event) { double y = event.y / (double)(allocation.height - margin_bottom); if (y < 0) y = 0; if (y > 1) y = 1; @@ -688,6 +273,7 @@ namespace Ddb { if (preamp_hook) { preamp = y; + on_changed (); queue_draw(); return false; } @@ -699,43 +285,31 @@ namespace Ddb { if (curve_hook) { - if (snap) - snap_move (x, y); - else - { - current_point.data.x = x; - - if ((current_point.prev != null) && - current_point.prev.data.x > current_point.data.x) - current_point.data.x = current_point.prev.data.x; - - - if ((current_point.next != null) && - current_point.next.data.x < current_point.data.x) - current_point.data.x = current_point.next.data.x; - - current_point.data.y = y; - - if (current_point.data.x > 1) current_point.data.x = 1; - if (current_point.data.x < 0) current_point.data.x = 0; - } - - recalc_values(); + update_eq_drag ((int)event.x, (int)event.y); mouse_y = (int)event.y; - queue_draw (); - } - else - { - if (!get_point_at (x, y)) - get_window().set_cursor (pointer_cursor); - else - get_window().set_cursor (moving_cursor); - queue_draw (); } + queue_draw (); return false; } -// public static Equalizer inst = null; + public void + set_band (int band, double v) { + values[band] = 1 - (v + 20.0) / 40.0; + } + + public double + get_band (int band) { + return ((1 - values[band]) * 40.0) - 20.0; + } + public void + set_preamp (double v) { + preamp = 1 - (v + 20.0) / 40.0; + } + + public double + get_preamp () { + return ((1 - preamp) * 40.0) - 20.0; + } } } |