From 35a966c824a862deec9691f6b3ea665f0f8a1dd6 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Fri, 22 Apr 2011 16:18:51 +0000 Subject: [PATCH] fix up fwd/reverse stuff in semitone mode git-svn-id: svn://localhost/ardour2/branches/3.0@9407 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/shuttle_control.cc | 127 +++++++++++++++++++++++---------- gtk2_ardour/shuttle_control.h | 9 +-- 2 files changed, 95 insertions(+), 41 deletions(-) diff --git a/gtk2_ardour/shuttle_control.cc b/gtk2_ardour/shuttle_control.cc index 357094959c..c941336de5 100644 --- a/gtk2_ardour/shuttle_control.cc +++ b/gtk2_ardour/shuttle_control.cc @@ -112,14 +112,16 @@ ShuttleControl::map_transport_state () { float speed = _session->transport_speed (); - if (speed != 0.0) { + if (fabs(speed) <= (2*DBL_EPSILON)) { + shuttle_fract = 0; + } else { if (Config->get_shuttle_units() == Semitones) { - shuttle_fract = semitones_as_fract (speed_as_semitones (speed)); + bool reverse; + int semi = speed_as_semitones (speed, reverse); + shuttle_fract = semitones_as_fract (semi, reverse); } else { shuttle_fract = speed/shuttle_max_speed; } - } else { - shuttle_fract = 0; } queue_draw (); @@ -296,21 +298,46 @@ ShuttleControl::on_scroll_event (GdkEventScroll* ev) return true; } - switch (ev->direction) { - - case GDK_SCROLL_UP: + switch (ev->direction) { + case GDK_SCROLL_UP: case GDK_SCROLL_RIGHT: shuttle_fract += 0.005; - break; - case GDK_SCROLL_DOWN: + break; + case GDK_SCROLL_DOWN: case GDK_SCROLL_LEFT: shuttle_fract -= 0.005; - break; - default: - return false; - } + break; + default: + return false; + } + + if (Config->get_shuttle_units() == Semitones) { + + float lower_side_of_dead_zone = semitones_as_fract (-24, true); + float upper_side_of_dead_zone = semitones_as_fract (-24, false); + + /* if we entered the "dead zone" (-24 semitones in forward or reverse), jump + to the far side of it. + */ + + if (shuttle_fract > lower_side_of_dead_zone && shuttle_fract < upper_side_of_dead_zone) { + switch (ev->direction) { + case GDK_SCROLL_UP: + case GDK_SCROLL_RIGHT: + shuttle_fract = upper_side_of_dead_zone; + break; + case GDK_SCROLL_DOWN: + case GDK_SCROLL_LEFT: + shuttle_fract = lower_side_of_dead_zone; + break; + default: + /* impossible, checked above */ + return false; + } + } + } - use_shuttle_fract (true); + use_shuttle_fract (true); return true; } @@ -355,33 +382,41 @@ ShuttleControl::set_shuttle_fract (double f) } int -ShuttleControl::speed_as_semitones (float speed) +ShuttleControl::speed_as_semitones (float speed, bool& reverse) { + assert (speed != 0.0); + if (speed < 0.0) { + reverse = true; return (int) round (12.0 * fast_log2 (-speed)); } else { + reverse = false; return (int) round (12.0 * fast_log2 (speed)); } } float -ShuttleControl::semitones_as_speed (int semi) +ShuttleControl::semitones_as_speed (int semi, bool reverse) { - return pow (2.0, (semi / 12.0)); + if (reverse) { + return -pow (2.0, (semi / 12.0)); + } else { + return pow (2.0, (semi / 12.0)); + } } float -ShuttleControl::semitones_as_fract (int semi) +ShuttleControl::semitones_as_fract (int semi, bool reverse) { - double const step = 1.0 / 24.0; // range is 24 semitones up & down - return semi * step; + float speed = semitones_as_speed (semi, reverse); + return speed/4.0; /* 4.0 is the maximum speed for a 24 semitone shift */ } int -ShuttleControl::fract_as_semitones (float fract) +ShuttleControl::fract_as_semitones (float fract, bool& reverse) { - double const step = 1.0 / 24.0; // range is 24 semitones up & down - return (int) round (shuttle_fract / step); + assert (fract != 0.0); + return speed_as_semitones (fract * 4.0, reverse); } void @@ -389,13 +424,8 @@ ShuttleControl::use_shuttle_fract (bool force) { microseconds_t now = get_microseconds(); - if (Config->get_shuttle_units() == Semitones) { - shuttle_fract = max (-1.0f, shuttle_fract); - shuttle_fract = min (1.0f, shuttle_fract); - } else { - shuttle_fract = max (-shuttle_max_speed, shuttle_fract); - shuttle_fract = min (shuttle_max_speed, shuttle_fract); - } + shuttle_fract = max (-1.0f, shuttle_fract); + shuttle_fract = min (1.0f, shuttle_fract); /* do not attempt to submit a motion-driven transport speed request more than once per process cycle. @@ -409,11 +439,17 @@ ShuttleControl::use_shuttle_fract (bool force) double speed = 0; - if (Config->get_shuttle_units() == Semitones) { - speed = semitones_as_speed (fract_as_semitones (shuttle_fract)); - } else { - speed = shuttle_max_speed * shuttle_fract; - } + if (Config->get_shuttle_units() == Semitones) { + if (shuttle_fract != 0.0) { + bool reverse; + int semi = fract_as_semitones (shuttle_fract, reverse); + speed = semitones_as_speed (semi, reverse); + } else { + speed = 0.0; + } + } else { + speed = shuttle_max_speed * shuttle_fract; + } _session->request_transport_speed_nonzero (speed); } @@ -452,16 +488,33 @@ ShuttleControl::on_expose_event (GdkEventExpose* event) /* speed text */ char buf[32]; + if (speed != 0) { + if (Config->get_shuttle_units() == Percentage) { + if (speed == 1.0) { snprintf (buf, sizeof (buf), _("Playing")); } else { - snprintf (buf, sizeof (buf), "%d%%", (int) round (speed * 100)); + if (speed < 0.0) { + snprintf (buf, sizeof (buf), "<<< %d%%", (int) round (-speed * 100)); + } else { + snprintf (buf, sizeof (buf), ">>> %d%%", (int) round (speed * 100)); + } } + } else { - snprintf (buf, sizeof (buf), "%+d semitones", speed_as_semitones (speed)); + + bool reversed; + int semi = speed_as_semitones (speed, reversed); + + if (reversed) { + snprintf (buf, sizeof (buf), _("<<< %+d semitones"), semi); + } else { + snprintf (buf, sizeof (buf), _(">>> %+d semitones"), semi); + } } + } else { snprintf (buf, sizeof (buf), _("Stopped")); } diff --git a/gtk2_ardour/shuttle_control.h b/gtk2_ardour/shuttle_control.h index 1306af292b..7f8176ea01 100644 --- a/gtk2_ardour/shuttle_control.h +++ b/gtk2_ardour/shuttle_control.h @@ -91,10 +91,11 @@ class ShuttleControl : public Gtk::DrawingArea, public ARDOUR::SessionHandlePtr void set_shuttle_units (ARDOUR::ShuttleUnits); void set_shuttle_style (ARDOUR::ShuttleBehaviour); - int speed_as_semitones (float); - float semitones_as_speed (int); - float semitones_as_fract (int); - int fract_as_semitones (float); + int speed_as_semitones (float, bool&); + int fract_as_semitones (float, bool&); + + float semitones_as_speed (int, bool); + float semitones_as_fract (int, bool); }; #endif /* __gtk2_ardour_shuttle_control_h__ */ -- 2.30.2