single button auto-punch feature

Nathan Stewart <[email protected]> Fri, 26 Aug 2016 22:18:44 -0400
Newsgroups gmane.comp.audio.ardour.devel
Message-ID <CACPio-65_GO1oM=cP6P2+O8HGcvq3t7pDrTMRWz_B6tfB-ogNA@mail.gmail.com>
Another control surface support feature - my Zoom's (and I suspect others)
"Punch In/Out" button when used as a standalone recorder works something
like this:

Press "Punch In" button (F1) and it sets the punch in point. Press it again
and it sets the punch out point. Press it a third time and it will clear
both punch in and out.  I created a function in gtk2_ardour/editor_ops.cc
to mimic this behavior. It does the above, with one exception not
explicitly defined by the recorder's docs - If Punch In has been set, and
the playhead is rewound before the punch-in point, pressing the button
again will move the punch-in point without setting the punch-out. Otherwise
behavior is as stated above.

Here's my proposed patch for it. Since this is for control surface support
- I didn't add it to the Edit menu, but it is accessible from the editor
actions menu. There's a feature request for this (
http://tracker.ardour.org/view.php?id=2903) going back to 2009.

Nathan

_______________________________________________
ardour-dev mailing list
[email protected]
http://lists.ardour.org/listinfo.cgi/ardour-dev-ardour.org
0001-Single-Button-Multi-press-Auto-Punch-In-Out-with-pun.patch (text/x-patch, 3.5 KB)
From 565f1f05944c77a2e990593a1770a176b1d6871f Mon Sep 17 00:00:00 2001
From: Nathan Stewart <[email protected]>
Date: Fri, 26 Aug 2016 22:04:55 -0400
Subject: [PATCH] Single Button, Multi-press Auto Punch In/Out with punch range

---
 gtk2_ardour/editor.h          |  1 +
 gtk2_ardour/editor_actions.cc |  1 +
 gtk2_ardour/editor_ops.cc     | 46 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 48 insertions(+)

diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index 7d754ed..6d3ad50 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -1451,6 +1451,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
 	void set_loop_from_selection (bool play);
 	void set_punch_from_selection ();
 	void set_punch_from_region ();
+	void set_punch_range_from_playhead();
 
 	void set_session_start_from_playhead ();
 	void set_session_end_from_playhead ();
diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc
index 44c66e3..1944187 100644
--- a/gtk2_ardour/editor_actions.cc
+++ b/gtk2_ardour/editor_actions.cc
@@ -330,6 +330,7 @@ Editor::register_actions ()
 
 	reg_sens (editor_actions, "set-playhead", _("Playhead to Mouse"), sigc::mem_fun(*this, &Editor::set_playhead_cursor));
 	reg_sens (editor_actions, "set-edit-point", _("Active Marker to Mouse"), sigc::mem_fun(*this, &Editor::set_edit_point));
+	reg_sens (editor_actions, "set-auto-punch-range", _("Set Auto Punch Range"), sigc::mem_fun(*this, &Editor::set_punch_range_from_playhead));
 
 	reg_sens (editor_actions, "duplicate-range", _("Duplicate Range"), sigc::bind (sigc::mem_fun(*this, &Editor::duplicate_range), false));
 
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc
index f7bbf2a..0bf5c46 100644
--- a/gtk2_ardour/editor_ops.cc
+++ b/gtk2_ardour/editor_ops.cc
@@ -6359,6 +6359,52 @@ Editor::set_punch_from_selection ()
 }
 
 void
+Editor::set_punch_range_from_playhead ()
+{
+	// Sets punch in/out and punch range from a single button:
+	// if punch-in is unset, set punch range from playhead to end, enable punch-in
+	// if punch-in is set, the next push sets punch-out, unless the playhead has been
+	//     rewound prior to the punch-in marker, in which case the start of the 
+        //     punch  range  will be moved to the current playhead position. 
+        //     punch-out will not be set
+	// if punch-out is set, the third press will disable both punch-in and punch-out
+        //     and the punch range will be cleared
+
+	if (_session == 0) {
+		return;
+	}
+
+	Location*  tpl = transport_punch_location();
+	framepos_t now = playhead_cursor->current_frame();
+	framepos_t begin = now;
+	framepos_t end = _session->current_end_frame();
+
+	if (!_session->config.get_punch_in()) {
+		set_punch_range (begin, end, _("Punch Range"));
+		_session->config.set_punch_in(true);
+	} else if (tpl && !_session->config.get_punch_out()) {
+		if (now < tpl->start()) {
+			// playhead has been rewound - move start back  and pretend nothing happened
+			begin = now;
+			set_punch_range (begin, end, _("Punch Range"));
+		} else {
+			// normal case for 2nd press - set the punch out
+			end = playhead_cursor->current_frame ();
+			set_punch_range (tpl->start(), now, _("Punch Range"));
+			_session->config.set_punch_out(true);
+		}
+	} else 	{
+	    _session->config.set_punch_out(false);
+	    _session->config.set_punch_in(false);
+	    if (tpl)
+	    {
+		_session->locations()->remove(tpl);
+            }
+	}
+
+}
+
+void
 Editor::set_session_extents_from_selection ()
 {
 	if (_session == 0) {
-- 
2.7.4