summaryrefslogtreecommitdiff
path: root/gtk2_ardour
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2007-06-27 15:51:50 +0000
committerDavid Robillard <d@drobilla.net>2007-06-27 15:51:50 +0000
commitd7bd270aa10b3a8669223debe4c1b572ae876e2b (patch)
treedb9ad92cb5096a54a9d7e91873fe73530ceaf21b /gtk2_ardour
parentd7afe01c307e35719dc1ee41c079f81f40f009df (diff)
Big ol' automation refactor.
Things with automation parameters now inherit from Automatable, which handles serialization, fetching/adding/removing parameters, etc. Use AutomationList everywhere instead of Curve, make Curve a member of AutomationList instead (towards other types of "Curve" needed for CC, among other things). Work towards MIDI CC sending "automation" tracks. git-svn-id: svn://localhost/ardour2/trunk@2069 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'gtk2_ardour')
-rw-r--r--gtk2_ardour/SConscript2
-rw-r--r--gtk2_ardour/audio_region_view.cc6
-rw-r--r--gtk2_ardour/audio_time_axis.cc264
-rw-r--r--gtk2_ardour/audio_time_axis.h20
-rw-r--r--gtk2_ardour/automation_gain_line.cc7
-rw-r--r--gtk2_ardour/automation_gain_line.h10
-rw-r--r--gtk2_ardour/automation_line.h4
-rw-r--r--gtk2_ardour/automation_midi_cc_line.cc76
-rw-r--r--gtk2_ardour/automation_midi_cc_line.h44
-rw-r--r--gtk2_ardour/automation_pan_line.cc7
-rw-r--r--gtk2_ardour/automation_pan_line.h7
-rw-r--r--gtk2_ardour/crossfade_edit.cc22
-rw-r--r--gtk2_ardour/crossfade_edit.h8
-rw-r--r--gtk2_ardour/crossfade_view.cc4
-rw-r--r--gtk2_ardour/curvetest.cc6
-rw-r--r--gtk2_ardour/editor_canvas_events.cc5
-rw-r--r--gtk2_ardour/editor_items.h2
-rw-r--r--gtk2_ardour/editor_mouse.cc17
-rw-r--r--gtk2_ardour/gain_automation_time_axis.cc16
-rw-r--r--gtk2_ardour/gain_automation_time_axis.h9
-rw-r--r--gtk2_ardour/gain_meter.cc32
-rw-r--r--gtk2_ardour/ladspa_pluginui.cc19
-rw-r--r--gtk2_ardour/midi_controller_time_axis.cc81
-rw-r--r--gtk2_ardour/midi_controller_time_axis.h54
-rw-r--r--gtk2_ardour/midi_time_axis.cc85
-rw-r--r--gtk2_ardour/midi_time_axis.h9
-rw-r--r--gtk2_ardour/mixer_strip.cc8
-rw-r--r--gtk2_ardour/pan_automation_time_axis.cc5
-rw-r--r--gtk2_ardour/plugin_ui.h4
-rw-r--r--gtk2_ardour/redirect_automation_line.cc6
-rw-r--r--gtk2_ardour/redirect_automation_line.h6
-rw-r--r--gtk2_ardour/redirect_automation_time_axis.cc22
-rw-r--r--gtk2_ardour/redirect_automation_time_axis.h5
-rw-r--r--gtk2_ardour/redirect_box.cc2
-rw-r--r--gtk2_ardour/region_gain_line.cc4
-rw-r--r--gtk2_ardour/region_gain_line.h2
-rw-r--r--gtk2_ardour/route_time_axis.cc232
-rw-r--r--gtk2_ardour/route_time_axis.h42
38 files changed, 753 insertions, 401 deletions
diff --git a/gtk2_ardour/SConscript b/gtk2_ardour/SConscript
index c5e8f10856..cb5cc41ae2 100644
--- a/gtk2_ardour/SConscript
+++ b/gtk2_ardour/SConscript
@@ -96,6 +96,7 @@ audio_clock.cc
audio_time_axis.cc
audio_region_editor.cc
automation_gain_line.cc
+automation_midi_cc_line.cc
automation_line.cc
automation_pan_line.cc
automation_time_axis.cc
@@ -142,6 +143,7 @@ export_session_dialog.cc
export_region_dialog.cc
export_range_markers_dialog.cc
gain_automation_time_axis.cc
+midi_controller_time_axis.cc
gain_meter.cc
ghostregion.cc
gtk-custom-hruler.c
diff --git a/gtk2_ardour/audio_region_view.cc b/gtk2_ardour/audio_region_view.cc
index 991f15075a..058295949f 100644
--- a/gtk2_ardour/audio_region_view.cc
+++ b/gtk2_ardour/audio_region_view.cc
@@ -534,7 +534,7 @@ AudioRegionView::reset_fade_in_shape_width (nframes_t width)
fade_in_shape->show();
float curve[npoints];
- audio_region()->fade_in().get_vector (0, audio_region()->fade_in().back()->when, curve, npoints);
+ audio_region()->fade_in().curve().get_vector (0, audio_region()->fade_in().back()->when, curve, npoints);
points = get_canvas_points ("fade in shape", npoints+3);
@@ -620,7 +620,7 @@ AudioRegionView::reset_fade_out_shape_width (nframes_t width)
fade_out_shape->show();
float curve[npoints];
- audio_region()->fade_out().get_vector (0, audio_region()->fade_out().back()->when, curve, npoints);
+ audio_region()->fade_out().curve().get_vector (0, audio_region()->fade_out().back()->when, curve, npoints);
if (_height > NAME_HIGHLIGHT_THRESH) {
h = _height - NAME_HIGHLIGHT_SIZE;
@@ -953,7 +953,7 @@ AudioRegionView::add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev)
audio_region()->envelope().add (fx, y);
XMLNode &after = audio_region()->envelope().get_state();
- trackview.session().add_command (new MementoCommand<Curve>(audio_region()->envelope(), &before, &after));
+ trackview.session().add_command (new MementoCommand<AutomationList>(audio_region()->envelope(), &before, &after));
trackview.session().commit_reversible_command ();
}
diff --git a/gtk2_ardour/audio_time_axis.cc b/gtk2_ardour/audio_time_axis.cc
index f1160e26ec..b259d8723d 100644
--- a/gtk2_ardour/audio_time_axis.cc
+++ b/gtk2_ardour/audio_time_axis.cc
@@ -83,16 +83,12 @@ AudioTimeAxisView::AudioTimeAxisView (PublicEditor& ed, Session& sess, boost::sh
assert(!is_track() || is_audio_track());
subplugin_menu.set_name ("ArdourContextMenu");
- gain_track = 0;
- pan_track = 0;
waveform_item = 0;
- pan_automation_item = 0;
- gain_automation_item = 0;
_view = new AudioStreamView (*this);
- add_gain_automation_child ();
- add_pan_automation_child ();
+ create_automation_child (GainAutomation);
+ create_automation_child (PanAutomation);
ignore_toggle = false;
@@ -156,81 +152,6 @@ AudioTimeAxisView::hide ()
}
void
-AudioTimeAxisView::set_state (const XMLNode& node)
-{
- const XMLProperty *prop;
-
- TimeAxisView::set_state (node);
-
- if ((prop = node.property ("shown_editor")) != 0) {
- if (prop->value() == "no") {
- _marked_for_display = false;
- } else {
- _marked_for_display = true;
- }
- } else {
- _marked_for_display = true;
- }
-
- XMLNodeList nlist = node.children();
- XMLNodeConstIterator niter;
- XMLNode *child_node;
-
-
- show_gain_automation = false;
- show_pan_automation = false;
-
- for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
- child_node = *niter;
-
- if (child_node->name() == "gain") {
- XMLProperty *prop=child_node->property ("shown");
-
- if (prop != 0) {
- if (prop->value() == "yes") {
- show_gain_automation = true;
- }
- }
- continue;
- }
-
- if (child_node->name() == "pan") {
- XMLProperty *prop=child_node->property ("shown");
-
- if (prop != 0) {
- if (prop->value() == "yes") {
- show_pan_automation = true;
- }
- }
- continue;
- }
- }
-}
-
-void
-AudioTimeAxisView::build_automation_action_menu ()
-{
- using namespace Menu_Helpers;
-
- RouteTimeAxisView::build_automation_action_menu ();
-
- MenuList& automation_items = automation_action_menu->items();
-
- automation_items.push_back (SeparatorElem());
-
- automation_items.push_back (CheckMenuElem (_("Fader"),
- mem_fun(*this, &AudioTimeAxisView::toggle_gain_track)));
- gain_automation_item = static_cast<CheckMenuItem*> (&automation_items.back());
- gain_automation_item->set_active(show_gain_automation);
-
- automation_items.push_back (CheckMenuElem (_("Pan"),
- mem_fun(*this, &AudioTimeAxisView::toggle_pan_track)));
- pan_automation_item = static_cast<CheckMenuItem*> (&automation_items.back());
- pan_automation_item->set_active(show_pan_automation);
-
-}
-
-void
AudioTimeAxisView::append_extra_display_menu_items ()
{
using namespace Menu_Helpers;
@@ -360,79 +281,45 @@ AudioTimeAxisView::set_waveform_scale (WaveformScale scale)
}
void
-AudioTimeAxisView::add_gain_automation_child ()
+AudioTimeAxisView::create_automation_child (ParamID param)
{
- XMLProperty* prop;
- AutomationLine* line;
-
- gain_track = new GainAutomationTimeAxisView (_session,
- _route,
- editor,
- *this,
- parent_canvas,
- _("gain"),
- _route->gain_automation_curve());
-
- line = new AutomationGainLine ("automation gain",
- _session,
- *gain_track,
- *gain_track->canvas_display,
- _route->gain_automation_curve());
+ if (param.type() == GainAutomation) {
+ GainAutomationTimeAxisView* gain_track = new GainAutomationTimeAxisView (_session,
+ _route,
+ editor,
+ *this,
+ parent_canvas,
+ _route->describe_parameter(param),
+ _route->gain_automation());
- line->set_line_color (Config->canvasvar_AutomationLine.get());
-
+ AutomationLine* line = new AutomationGainLine ("automation gain",
+ *gain_track,
+ *gain_track->canvas_display,
+ _route->gain_automation());
- gain_track->add_line (*line);
+ line->set_line_color (Config->canvasvar_AutomationLine.get());
- add_child (gain_track);
+ gain_track->add_line (*line);
- gain_track->Hiding.connect (mem_fun(*this, &AudioTimeAxisView::gain_hidden));
+ add_automation_child(ParamID(GainAutomation), gain_track);
- bool hideit = true;
-
- XMLNode* node;
-
- if ((node = gain_track->get_state_node()) != 0) {
- if ((prop = node->property ("shown")) != 0) {
- if (prop->value() == "yes") {
- hideit = false;
- }
- }
- }
+ } else if (param.type() == PanAutomation) {
- if (hideit) {
- gain_track->hide ();
- }
-}
+ PanAutomationTimeAxisView* pan_track = new PanAutomationTimeAxisView (_session,
+ _route,
+ editor,
+ *this,
+ parent_canvas,
+ _route->describe_parameter(param));
-void
-AudioTimeAxisView::add_pan_automation_child ()
-{
- XMLProperty* prop;
-
- pan_track = new PanAutomationTimeAxisView (_session, _route, editor, *this, parent_canvas, _("pan"));
-
- update_pans ();
-
- add_child (pan_track);
-
- pan_track->Hiding.connect (mem_fun(*this, &AudioTimeAxisView::pan_hidden));
+ ensure_xml_node ();
- ensure_xml_node ();
- bool hideit = true;
-
- XMLNode* node;
-
- if ((node = pan_track->get_state_node()) != 0) {
- if ((prop = node->property ("shown")) != 0) {
- if (prop->value() == "yes") {
- hideit = false;
- }
- }
- }
+ add_automation_child(ParamID(PanAutomation), pan_track);
+
+ update_pans ();
- if (hideit) {
- pan_track->hide ();
+ } else {
+ error << "AudioTimeAxisView: unknown automation child " << param.to_string() << endmsg;
}
}
@@ -441,6 +328,14 @@ AudioTimeAxisView::update_pans ()
{
Panner::iterator p;
+ RouteAutomationNode* ran = automation_track(PanAutomation);
+ if (!ran) {
+ warning << _route << " has no pan automation track" << endmsg;
+ return;
+ }
+
+ AutomationTimeAxisView* pan_track = ran->track;
+
pan_track->clear_lines ();
/* we don't draw lines for "greater than stereo" panning.
@@ -454,7 +349,7 @@ AudioTimeAxisView::update_pans ()
AutomationLine* line;
- line = new AutomationPanLine ("automation pan", _session, *pan_track,
+ line = new AutomationPanLine ("automation pan", *pan_track,
*pan_track->canvas_display,
(*p)->automation());
@@ -471,79 +366,6 @@ AudioTimeAxisView::update_pans ()
}
void
-AudioTimeAxisView::toggle_gain_track ()
-{
-
- bool showit = gain_automation_item->get_active();
-
- if (showit != gain_track->marked_for_display()) {
- if (showit) {
- gain_track->set_marked_for_display (true);
- gain_track->canvas_display->show();
- gain_track->get_state_node()->add_property ("shown", X_("yes"));
- } else {
- gain_track->set_marked_for_display (false);
- gain_track->hide ();
- gain_track->get_state_node()->add_property ("shown", X_("no"));
- }
-
- /* now trigger a redisplay */
-
- if (!no_redraw) {
- _route->gui_changed (X_("track_height"), (void *) 0); /* EMIT_SIGNAL */
- }
- }
-}
-
-void
-AudioTimeAxisView::gain_hidden ()
-{
- gain_track->get_state_node()->add_property (X_("shown"), X_("no"));
-
- if (gain_automation_item && !_hidden) {
- gain_automation_item->set_active (false);
- }
-
- _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
-}
-
-void
-AudioTimeAxisView::toggle_pan_track ()
-{
- bool showit = pan_automation_item->get_active();
-
- if (showit != pan_track->marked_for_display()) {
- if (showit) {
- pan_track->set_marked_for_display (true);
- pan_track->canvas_display->show();
- pan_track->get_state_node()->add_property ("shown", X_("yes"));
- } else {
- pan_track->set_marked_for_display (false);
- pan_track->hide ();
- pan_track->get_state_node()->add_property ("shown", X_("no"));
- }
-
- /* now trigger a redisplay */
-
- if (!no_redraw) {
- _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
- }
- }
-}
-
-void
-AudioTimeAxisView::pan_hidden ()
-{
- pan_track->get_state_node()->add_property ("shown", "no");
-
- if (pan_automation_item && !_hidden) {
- pan_automation_item->set_active (false);
- }
-
- _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
-}
-
-void
AudioTimeAxisView::show_all_automation ()
{
no_redraw = true;
@@ -669,12 +491,6 @@ AudioTimeAxisView::update_control_names ()
}
}
-XMLNode*
-AudioTimeAxisView::get_child_xml_node (const string & childname)
-{
- return RouteUI::get_child_xml_node (childname);
-}
-
void
AudioTimeAxisView::set_layer_display (LayerDisplay d)
{
diff --git a/gtk2_ardour/audio_time_axis.h b/gtk2_ardour/audio_time_axis.h
index ab5ef955c7..a2f331cf6a 100644
--- a/gtk2_ardour/audio_time_axis.h
+++ b/gtk2_ardour/audio_time_axis.h
@@ -83,16 +83,14 @@ class AudioTimeAxisView : public RouteTimeAxisView
guint32 show_at (double y, int& nth, Gtk::VBox *parent);
void hide ();
- void set_state (const XMLNode&);
- XMLNode* get_child_xml_node (const string & childname);
-
+ void create_automation_child (ARDOUR::ParamID param);
+
private:
friend class AudioStreamView;
friend class AudioRegionView;
void route_active_changed ();
- void build_automation_action_menu ();
void append_extra_display_menu_items ();
void toggle_show_waveforms ();
@@ -104,26 +102,12 @@ class AudioTimeAxisView : public RouteTimeAxisView
void show_existing_automation ();
void hide_all_automation ();
- void add_gain_automation_child ();
- void add_pan_automation_child ();
- void add_parameter_automation_child ();
-
- void toggle_gain_track ();
- void toggle_pan_track ();
-
void gain_hidden ();
void pan_hidden ();
void update_pans ();
void update_control_names ();
- AutomationTimeAxisView* gain_track;
- AutomationTimeAxisView* pan_track;
-
- // Set from XML so context menu automation buttons can be correctly initialized
- bool show_gain_automation;
- bool show_pan_automation;
-
Gtk::CheckMenuItem* waveform_item;
Gtk::RadioMenuItem* traditional_item;
Gtk::RadioMenuItem* rectified_item;
diff --git a/gtk2_ardour/automation_gain_line.cc b/gtk2_ardour/automation_gain_line.cc
index 006543df18..84488dc2b5 100644
--- a/gtk2_ardour/automation_gain_line.cc
+++ b/gtk2_ardour/automation_gain_line.cc
@@ -26,16 +26,13 @@
#include "automation_gain_line.h"
#include "utils.h"
-#include <ardour/session.h>
-
using namespace std;
using namespace ARDOUR;
using namespace PBD;
-AutomationGainLine::AutomationGainLine (const string & name, Session& s, TimeAxisView& tv, ArdourCanvas::Group& parent, Curve& c)
+AutomationGainLine::AutomationGainLine (const string & name, TimeAxisView& tv, ArdourCanvas::Group& parent, AutomationList& l)
- : AutomationLine (name, tv, parent, c),
- session (s)
+ : AutomationLine (name, tv, parent, l)
{
set_verbose_cursor_uses_gain_mapping (true);
}
diff --git a/gtk2_ardour/automation_gain_line.h b/gtk2_ardour/automation_gain_line.h
index ca90216c8f..fe8c9274f2 100644
--- a/gtk2_ardour/automation_gain_line.h
+++ b/gtk2_ardour/automation_gain_line.h
@@ -25,23 +25,15 @@
#include "canvas.h"
#include "automation_line.h"
-namespace ARDOUR {
- class Session;
-}
-
class TimeAxisView;
class AutomationGainLine : public AutomationLine
{
public:
- AutomationGainLine (const string & name, ARDOUR::Session&, TimeAxisView&, ArdourCanvas::Group& parent, ARDOUR::Curve&);
+ AutomationGainLine (const string & name, TimeAxisView&, ArdourCanvas::Group& parent, ARDOUR::AutomationList&);
void view_to_model_y (double&);
void model_to_view_y (double&);
-
- private:
- ARDOUR::Session& session;
-
};
diff --git a/gtk2_ardour/automation_line.h b/gtk2_ardour/automation_line.h
index 2637a0c554..41034dbf6e 100644
--- a/gtk2_ardour/automation_line.h
+++ b/gtk2_ardour/automation_line.h
@@ -56,7 +56,7 @@ namespace Gnome {
class ControlPoint
{
public:
- ControlPoint (AutomationLine& al);
+ ControlPoint (AutomationLine& al);
ControlPoint (const ControlPoint&, bool dummy_arg_to_force_special_copy_constructor);
virtual ~ControlPoint ();
@@ -98,7 +98,7 @@ class ControlPoint
class AutomationLine : public sigc::trackable, public PBD::StatefulThingWithGoingAway
{
public:
- AutomationLine (const string & name, TimeAxisView&, ArdourCanvas::Group&, ARDOUR::AutomationList&);
+ AutomationLine (const string & name, TimeAxisView&, ArdourCanvas::Group&, ARDOUR::AutomationList&);
virtual ~AutomationLine ();
void queue_reset ();
diff --git a/gtk2_ardour/automation_midi_cc_line.cc b/gtk2_ardour/automation_midi_cc_line.cc
new file mode 100644
index 0000000000..4a074ddbe9
--- /dev/null
+++ b/gtk2_ardour/automation_midi_cc_line.cc
@@ -0,0 +1,76 @@
+/*
+ Copyright (C) 2000-2007 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <sigc++/signal.h>
+
+#include <ardour/curve.h>
+
+#include "automation_midi_cc_line.h"
+
+using namespace std;
+using namespace ARDOUR;
+using namespace PBD;
+
+AutomationMidiCCLine::AutomationMidiCCLine (const string & name, TimeAxisView& tv, ArdourCanvas::Group& parent, AutomationList& l)
+
+ : AutomationLine (name, tv, parent, l)
+{
+ set_verbose_cursor_uses_gain_mapping (true);
+}
+
+void
+AutomationMidiCCLine::view_to_model_y (double& y)
+{
+ assert(y >= 0);
+ assert(y <= 1);
+
+ y = (int)(y * 127.0);
+
+ assert(y >= 0);
+ assert(y <= 127);
+}
+
+void
+AutomationMidiCCLine::model_to_view_y (double& y)
+{
+ assert(y >= 0);
+ assert(y <= 127);
+
+ y = y / 127.0;
+
+ assert(y >= 0);
+ assert(y <= 1);
+}
+
+string
+AutomationMidiCCLine::get_verbose_cursor_string (float fraction)
+{
+ static const size_t MAX_VAL_LEN = 4; // 4 for "127\0"
+ char buf[MAX_VAL_LEN];
+
+ double cc_val = fraction;
+ view_to_model_y(cc_val); // 0..127
+
+ snprintf (buf, MAX_VAL_LEN, "%u", (unsigned)cc_val);
+
+ return buf;
+}
+
+
+
diff --git a/gtk2_ardour/automation_midi_cc_line.h b/gtk2_ardour/automation_midi_cc_line.h
new file mode 100644
index 0000000000..6ac078a911
--- /dev/null
+++ b/gtk2_ardour/automation_midi_cc_line.h
@@ -0,0 +1,44 @@
+/*
+ Copyright (C) 2000-2007 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef __ardour_gtk_automation_midi_cc_line_h__
+#define __ardour_gtk_automation_midi_cc_line_h__
+
+#include <ardour/ardour.h>
+
+#include "canvas.h"
+#include "automation_line.h"
+
+class TimeAxisView;
+
+class AutomationMidiCCLine : public AutomationLine
+{
+ public:
+ AutomationMidiCCLine (const string & name, TimeAxisView&, ArdourCanvas::Group& parent, ARDOUR::AutomationList&);
+
+ void view_to_model_y (double&);
+ void model_to_view_y (double&);
+
+ string get_verbose_cursor_string (float);
+};
+
+
+#endif /* __ardour_gtk_automation_midi_cc_line_h__ */
+
+
diff --git a/gtk2_ardour/automation_pan_line.cc b/gtk2_ardour/automation_pan_line.cc
index 04cfb0a311..0e36f4ef88 100644
--- a/gtk2_ardour/automation_pan_line.cc
+++ b/gtk2_ardour/automation_pan_line.cc
@@ -27,15 +27,12 @@
#include "utils.h"
#include <cmath>
-#include <ardour/session.h>
-
using namespace ARDOUR;
using namespace PBD;
-AutomationPanLine::AutomationPanLine (const string & name, Session& s, TimeAxisView& tv, ArdourCanvas::Group& parent, Curve& c)
+AutomationPanLine::AutomationPanLine (const string & name, TimeAxisView& tv, ArdourCanvas::Group& parent, AutomationList& l)
- : AutomationLine (name, tv, parent, c),
- session (s)
+ : AutomationLine (name, tv, parent, l)
{
}
diff --git a/gtk2_ardour/automation_pan_line.h b/gtk2_ardour/automation_pan_line.h
index c6b32cbc92..6374c535e0 100644
--- a/gtk2_ardour/automation_pan_line.h
+++ b/gtk2_ardour/automation_pan_line.h
@@ -25,22 +25,17 @@
#include "canvas.h"
#include "automation_line.h"
-namespace ARDOUR {
- class Session;
-}
-
class TimeAxisView;
class AutomationPanLine : public AutomationLine
{
public:
- AutomationPanLine (const string & name, ARDOUR::Session&, TimeAxisView&, ArdourCanvas::Group& parent, ARDOUR::Curve&);
+ AutomationPanLine (const string & name, TimeAxisView&, ArdourCanvas::Group& parent, ARDOUR::AutomationList&);
void view_to_model_y (double&);
void model_to_view_y (double&);
private:
- ARDOUR::Session& session;
vector<ArdourCanvas::Item*> lines;
};
diff --git a/gtk2_ardour/crossfade_edit.cc b/gtk2_ardour/crossfade_edit.cc
index 349297f8cd..fd677ac4a6 100644
--- a/gtk2_ardour/crossfade_edit.cc
+++ b/gtk2_ardour/crossfade_edit.cc
@@ -66,8 +66,8 @@ CrossfadeEditor::Presets* CrossfadeEditor::fade_out_presets = 0;
CrossfadeEditor::Half::Half ()
: line (0),
- normative_curve (0.0, 1.0, 1.0, true),
- gain_curve (0.0, 2.0, 1.0, true)
+ normative_curve (ParamID(GainAutomation), 0.0, 1.0, 1.0), // FIXME: GainAutomation?
+ gain_curve (ParamID(GainAutomation), 0.0, 2.0, 1.0)
{
}
@@ -327,10 +327,10 @@ CrossfadeEditor::audition_state_changed (bool yn)
}
void
-CrossfadeEditor::set (const ARDOUR::Curve& curve, WhichFade which)
+CrossfadeEditor::set (const ARDOUR::AutomationList& curve, WhichFade which)
{
double firstx, endx;
- ARDOUR::Curve::const_iterator the_end;
+ ARDOUR::AutomationList::const_iterator the_end;
for (list<Point*>::iterator i = fade[which].points.begin(); i != fade[which].points.end(); ++i) {
delete *i;
@@ -350,7 +350,7 @@ CrossfadeEditor::set (const ARDOUR::Curve& curve, WhichFade which)
firstx = (*curve.const_begin())->when;
endx = (*the_end)->when;
- for (ARDOUR::Curve::const_iterator i = curve.const_begin(); i != curve.const_end(); ++i) {
+ for (ARDOUR::AutomationList::const_iterator i = curve.const_begin(); i != curve.const_end(); ++i) {
double xfract = ((*i)->when - firstx) / (endx - firstx);
double yfract = ((*i)->value - miny) / (maxy - miny);
@@ -644,7 +644,7 @@ CrossfadeEditor::redraw ()
size_t npoints = (size_t) effective_width();
float vec[npoints];
- fade[current].normative_curve.get_vector (0, 1.0, vec, npoints);
+ fade[current].normative_curve.curve().get_vector (0, 1.0, vec, npoints);
ArdourCanvas::Points pts;
ArdourCanvas::Points spts;
@@ -760,13 +760,13 @@ CrossfadeEditor::apply ()
void
CrossfadeEditor::_apply_to (boost::shared_ptr<Crossfade> xf)
{
- ARDOUR::Curve& in (xf->fade_in());
- ARDOUR::Curve& out (xf->fade_out());
+ ARDOUR::AutomationList& in (xf->fade_in());
+ ARDOUR::AutomationList& out (xf->fade_out());
/* IN */
- ARDOUR::Curve::const_iterator the_end = in.const_end();
+ ARDOUR::AutomationList::const_iterator the_end = in.const_end();
--the_end;
double firstx = (*in.begin())->when;
@@ -813,8 +813,8 @@ CrossfadeEditor::setup (boost::shared_ptr<Crossfade> xfade)
{
_apply_to (xfade);
xfade->set_active (true);
- xfade->fade_in().solve ();
- xfade->fade_out().solve ();
+ xfade->fade_in().curve().solve ();
+ xfade->fade_out().curve().solve ();
}
void
diff --git a/gtk2_ardour/crossfade_edit.h b/gtk2_ardour/crossfade_edit.h
index 715aa1a360..e9f2dcf762 100644
--- a/gtk2_ardour/crossfade_edit.h
+++ b/gtk2_ardour/crossfade_edit.h
@@ -33,7 +33,7 @@
namespace ARDOUR
{
class Session;
- class Curve;
+ class AutomationList;
class Crossfade;
}
@@ -105,8 +105,8 @@ class CrossfadeEditor : public ArdourDialog
ArdourCanvas::Line* line;
ArdourCanvas::Polygon* shading;
list<Point*> points;
- ARDOUR::Curve normative_curve; /* 0 - 1.0, linear */
- ARDOUR::Curve gain_curve; /* 0 - 2.0, gain mapping */
+ ARDOUR::AutomationList normative_curve; /* 0 - 1.0, linear */
+ ARDOUR::AutomationList gain_curve; /* 0 - 2.0, gain mapping */
vector<ArdourCanvas::WaveView*> waves;
Half();
@@ -176,7 +176,7 @@ class CrossfadeEditor : public ArdourDialog
double x_coordinate (double& xfract) const;
double y_coordinate (double& yfract) const;
- void set (const ARDOUR::Curve& alist, WhichFade);
+ void set (const ARDOUR::AutomationList& alist, WhichFade);
sigc::connection peaks_ready_connection;
diff --git a/gtk2_ardour/crossfade_view.cc b/gtk2_ardour/crossfade_view.cc
index d2fdd94e03..cf19137d98 100644
--- a/gtk2_ardour/crossfade_view.cc
+++ b/gtk2_ardour/crossfade_view.cc
@@ -189,7 +189,7 @@ CrossfadeView::redraw_curves ()
points = get_canvas_points ("xfade edit redraw", npoints);
vec = new float[npoints];
- crossfade->fade_in().get_vector (0, crossfade->length(), vec, npoints);
+ crossfade->fade_in().curve().get_vector (0, crossfade->length(), vec, npoints);
for (int i = 0, pci = 0; i < npoints; ++i) {
Art::Point &p = (*points)[pci++];
p.set_x(i);
@@ -197,7 +197,7 @@ CrossfadeView::redraw_curves ()
}
fade_in->property_points() = *points;
- crossfade->fade_out().get_vector (0, crossfade->length(), vec, npoints);
+ crossfade->fade_out().curve().get_vector (0, crossfade->length(), vec, npoints);
for (int i = 0, pci = 0; i < npoints; ++i) {
Art::Point &p = (*points)[pci++];
p.set_x(i);
diff --git a/gtk2_ardour/curvetest.cc b/gtk2_ardour/curvetest.cc
index 63804bd1b4..71f0600f32 100644
--- a/gtk2_ardour/curvetest.cc
+++ b/gtk2_ardour/curvetest.cc
@@ -33,7 +33,7 @@ curvetest (string filename)
{
ifstream in (filename.c_str());
stringstream line;
- Curve c (-1.0, +1.0, 0, true);
+ AutomationList al (ParamID(), -1.0, +1.0, 0);
double minx = DBL_MAX;
double maxx = DBL_MIN;
@@ -55,13 +55,13 @@ curvetest (string filename)
maxx = x;
}
- c.add (x, y);
+ al.add (x, y);
}
float foo[1024];
- c.get_vector (minx, maxx, foo, 1024);
+ al.curve().get_vector (minx, maxx, foo, 1024);
for (int i = 0; i < 1024; ++i) {
cout << minx + (((double) i / 1024.0) * (maxx - minx)) << ' ' << foo[i] << endl;
diff --git a/gtk2_ardour/editor_canvas_events.cc b/gtk2_ardour/editor_canvas_events.cc
index 40bef304c5..e1ed2d2fa1 100644
--- a/gtk2_ardour/editor_canvas_events.cc
+++ b/gtk2_ardour/editor_canvas_events.cc
@@ -35,6 +35,7 @@
#include "region_gain_line.h"
#include "automation_gain_line.h"
#include "automation_pan_line.h"
+#include "automation_midi_cc_line.h"
#include "automation_time_axis.h"
#include "redirect_automation_line.h"
#include "canvas_impl.h"
@@ -592,6 +593,8 @@ Editor::canvas_control_point_event (GdkEvent *event, ArdourCanvas::Item* item, C
type = PanAutomationControlPointItem;
} else if (dynamic_cast<RedirectAutomationLine*> (&cp->line) != 0) {
type = RedirectAutomationControlPointItem;
+ } else if (dynamic_cast<AutomationMidiCCLine*> (&cp->line) != 0) {
+ type = MidiCCAutomationControlPointItem;
} else {
return false;
}
@@ -612,6 +615,8 @@ Editor::canvas_line_event (GdkEvent *event, ArdourCanvas::Item* item, Automation
type = PanAutomationLineItem;
} else if (dynamic_cast<RedirectAutomationLine*> (al) != 0) {
type = RedirectAutomationLineItem;
+ } else if (dynamic_cast<AutomationMidiCCLine*> (al) != 0) {
+ type = MidiCCAutomationLineItem;
} else {
return false;
}
diff --git a/gtk2_ardour/editor_items.h b/gtk2_ardour/editor_items.h
index ad1d63b5bf..ddba43350a 100644
--- a/gtk2_ardour/editor_items.h
+++ b/gtk2_ardour/editor_items.h
@@ -38,6 +38,8 @@ enum ItemType {
PanAutomationLineItem,
RedirectAutomationControlPointItem,
RedirectAutomationLineItem,
+ MidiCCAutomationControlPointItem,
+ MidiCCAutomationLineItem,
MeterMarkerItem,
TempoMarkerItem,
MeterBarItem,
diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc
index 2f671c77eb..773c26f67d 100644
--- a/gtk2_ardour/editor_mouse.cc
+++ b/gtk2_ardour/editor_mouse.cc
@@ -350,6 +350,7 @@ Editor::button_selection (ArdourCanvas::Item* item, GdkEvent* event, ItemType it
case GainAutomationControlPointItem:
case PanAutomationControlPointItem:
case RedirectAutomationControlPointItem:
+ case MidiCCAutomationControlPointItem:
commit = set_selected_track_from_click (press, op, true);
if (mouse_mode != MouseRange) {
commit |= set_selected_control_point_from_click (op, false);
@@ -539,6 +540,7 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp
case GainAutomationControlPointItem:
case PanAutomationControlPointItem:
case RedirectAutomationControlPointItem:
+ case MidiCCAutomationControlPointItem:
start_control_point_grab (item, event);
return true;
break;
@@ -546,6 +548,7 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp
case GainAutomationLineItem:
case PanAutomationLineItem:
case RedirectAutomationLineItem:
+ case MidiCCAutomationLineItem:
start_line_grab_from_line (item, event);
return true;
break;
@@ -608,6 +611,7 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp
case GainAutomationControlPointItem:
case PanAutomationControlPointItem:
case RedirectAutomationControlPointItem:
+ case MidiCCAutomationControlPointItem:
start_control_point_grab (item, event);
return true;
break;
@@ -622,12 +626,14 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp
case GainAutomationControlPointItem:
case PanAutomationControlPointItem:
case RedirectAutomationControlPointItem:
+ case MidiCCAutomationControlPointItem:
start_control_point_grab (item, event);
break;
case GainAutomationLineItem:
case PanAutomationLineItem:
case RedirectAutomationLineItem:
+ case MidiCCAutomationLineItem:
start_line_grab_from_line (item, event);
break;
@@ -682,6 +688,7 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp
case GainAutomationControlPointItem:
case PanAutomationControlPointItem:
case RedirectAutomationControlPointItem:
+ case MidiCCAutomationControlPointItem:
start_control_point_grab (item, event);
return true;
break;
@@ -896,6 +903,7 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
case GainAutomationControlPointItem:
case PanAutomationControlPointItem:
case RedirectAutomationControlPointItem:
+ case MidiCCAutomationControlPointItem:
remove_control_point (item, event);
break;
@@ -917,6 +925,7 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
case GainAutomationLineItem:
case PanAutomationLineItem:
case RedirectAutomationLineItem:
+ case MidiCCAutomationLineItem:
case StartSelectionTrimItem:
case EndSelectionTrimItem:
return true;
@@ -1061,6 +1070,7 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
case GainAutomationControlPointItem:
case PanAutomationControlPointItem:
case RedirectAutomationControlPointItem:
+ case MidiCCAutomationControlPointItem:
if (mouse_mode == MouseGain || mouse_mode == MouseObject) {
cp = static_cast<ControlPoint*>(item->get_data ("control_point"));
cp->set_visible (true);
@@ -1096,6 +1106,7 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
case GainAutomationLineItem:
case RedirectAutomationLineItem:
+ case MidiCCAutomationLineItem:
case PanAutomationLineItem:
if (mouse_mode == MouseGain || mouse_mode == MouseObject) {
{
@@ -1218,11 +1229,13 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
case GainLineItem:
case GainAutomationLineItem:
case RedirectAutomationLineItem:
+ case MidiCCAutomationLineItem:
case PanAutomationLineItem:
case GainControlPointItem:
case GainAutomationControlPointItem:
case PanAutomationControlPointItem:
case RedirectAutomationControlPointItem:
+ case MidiCCAutomationControlPointItem:
/* these do not affect the current entered track state */
clear_entered_track = false;
break;
@@ -1254,6 +1267,7 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
case GainAutomationControlPointItem:
case PanAutomationControlPointItem:
case RedirectAutomationControlPointItem:
+ case MidiCCAutomationControlPointItem:
cp = reinterpret_cast<ControlPoint*>(item->get_data ("control_point"));
if (cp->line.npoints() > 1) {
if (!cp->selected) {
@@ -1289,6 +1303,7 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
case GainLineItem:
case GainAutomationLineItem:
case RedirectAutomationLineItem:
+ case MidiCCAutomationLineItem:
case PanAutomationLineItem:
al = reinterpret_cast<AutomationLine*> (item->get_data ("line"));
{
@@ -1432,6 +1447,7 @@ Editor::motion_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item
case MarkerItem:
case GainControlPointItem:
case RedirectAutomationControlPointItem:
+ case MidiCCAutomationControlPointItem:
case GainAutomationControlPointItem:
case PanAutomationControlPointItem:
case TempoMarkerItem:
@@ -1442,6 +1458,7 @@ Editor::motion_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item
case SelectionItem:
case GainLineItem:
case RedirectAutomationLineItem:
+ case MidiCCAutomationLineItem:
case GainAutomationLineItem:
case PanAutomationLineItem:
case FadeInHandleItem:
diff --git a/gtk2_ardour/gain_automation_time_axis.cc b/gtk2_ardour/gain_automation_time_axis.cc
index 9890854d4b..509c941555 100644
--- a/gtk2_ardour/gain_automation_time_axis.cc
+++ b/gtk2_ardour/gain_automation_time_axis.cc
@@ -17,7 +17,7 @@
*/
-#include <ardour/curve.h>
+#include <ardour/automation_event.h>
#include <ardour/route.h>
#include <pbd/memento_command.h>
@@ -33,11 +33,11 @@ using namespace Gtk;
GainAutomationTimeAxisView::GainAutomationTimeAxisView (Session& s, boost::shared_ptr<Route> r,
PublicEditor& e, TimeAxisView& parent,
- ArdourCanvas::Canvas& canvas, const string & n, ARDOUR::Curve& c)
+ ArdourCanvas::Canvas& canvas, const string & n, ARDOUR::AutomationList& l)
: AxisView (s),
AutomationTimeAxisView (s, r, e, parent, canvas, n, X_("gain"), ""),
- curve (c)
+ list (l)
{
}
@@ -62,10 +62,10 @@ GainAutomationTimeAxisView::add_automation_event (ArdourCanvas::Item* item, GdkE
lines.front()->view_to_model_y (y);
_session.begin_reversible_command (_("add gain automation event"));
- XMLNode& before = curve.get_state();
- curve.add (when, y);
- XMLNode& after = curve.get_state();
- _session.commit_reversible_command (new MementoCommand<ARDOUR::Curve>(curve, &before, &after));
+ XMLNode& before = list.get_state();
+ list.add (when, y);
+ XMLNode& after = list.get_state();
+ _session.commit_reversible_command (new MementoCommand<ARDOUR::AutomationList>(list, &before, &after));
_session.set_dirty ();
}
@@ -73,6 +73,6 @@ void
GainAutomationTimeAxisView::set_automation_state (AutoState state)
{
if (!ignore_state_request) {
- route->set_gain_automation_state (state);
+ route->set_parameter_automation_state (ParamID(GainAutomation), state);
}
}
diff --git a/gtk2_ardour/gain_automation_time_axis.h b/gtk2_ardour/gain_automation_time_axis.h
index 25a97a1a97..3f07be4ace 100644
--- a/gtk2_ardour/gain_automation_time_axis.h
+++ b/gtk2_ardour/gain_automation_time_axis.h
@@ -24,8 +24,7 @@
#include "automation_time_axis.h"
namespace ARDOUR {
- class Redirect;
- class Curve;
+ class AutomationList;
}
class GainAutomationTimeAxisView : public AutomationTimeAxisView
@@ -37,16 +36,16 @@ class GainAutomationTimeAxisView : public AutomationTimeAxisView
TimeAxisView& parent_axis,
ArdourCanvas::Canvas& canvas,
const string & name,
- ARDOUR::Curve&);
+ ARDOUR::AutomationList&);
~GainAutomationTimeAxisView();
void add_automation_event (ArdourCanvas::Item *item, GdkEvent *event, nframes_t, double);
private:
- ARDOUR::Curve& curve;
+ ARDOUR::AutomationList& list;
- void automation_changed ();
+ void automation_changed ();
void set_automation_state (ARDOUR::AutoState);
};
diff --git a/gtk2_ardour/gain_meter.cc b/gtk2_ardour/gain_meter.cc
index f67682019e..a4eea61bfa 100644
--- a/gtk2_ardour/gain_meter.cc
+++ b/gtk2_ardour/gain_meter.cc
@@ -166,13 +166,17 @@ GainMeter::GainMeter (boost::shared_ptr<IO> io, Session& s)
using namespace Menu_Helpers;
gain_astate_menu.items().push_back (MenuElem (_("Manual"),
- bind (mem_fun (*_io, &IO::set_gain_automation_state), (AutoState) Off)));
+ bind (mem_fun (*_io, &IO::set_parameter_automation_state),
+ ParamID(GainAutomation), (AutoState) Off)));
gain_astate_menu.items().push_back (MenuElem (_("Play"),
- bind (mem_fun (*_io, &IO::set_gain_automation_state), (AutoState) Play)));
+ bind (mem_fun (*_io, &IO::set_parameter_automation_state),
+ ParamID(GainAutomation), (AutoState) Play)));
gain_astate_menu.items().push_back (MenuElem (_("Write"),
- bind (mem_fun (*_io, &IO::set_gain_automation_state), (AutoState) Write)));
+ bind (mem_fun (*_io, &IO::set_parameter_automation_state),
+ ParamID(GainAutomation), (AutoState) Write)));
gain_astate_menu.items().push_back (MenuElem (_("Touch"),
- bind (mem_fun (*_io, &IO::set_gain_automation_state), (AutoState) Touch)));
+ bind (mem_fun (*_io, &IO::set_parameter_automation_state),
+ ParamID(GainAutomation), (AutoState) Touch)));
gain_astyle_menu.items().push_back (MenuElem (_("Trim")));
gain_astyle_menu.items().push_back (MenuElem (_("Abs")));
@@ -183,8 +187,8 @@ GainMeter::GainMeter (boost::shared_ptr<IO> io, Session& s)
gain_automation_style_button.signal_button_press_event().connect (mem_fun(*this, &GainMeter::gain_automation_style_button_event), false);
gain_automation_state_button.signal_button_press_event().connect (mem_fun(*this, &GainMeter::gain_automation_state_button_event), false);
- r->gain_automation_curve().automation_state_changed.connect (mem_fun(*this, &GainMeter::gain_automation_state_changed));
- r->gain_automation_curve().automation_style_changed.connect (mem_fun(*this, &GainMeter::gain_automation_style_changed));
+ r->gain_automation().automation_state_changed.connect (mem_fun(*this, &GainMeter::gain_automation_state_changed));
+ r->gain_automation().automation_style_changed.connect (mem_fun(*this, &GainMeter::gain_automation_style_changed));
fader_vbox->pack_start (gain_automation_state_button, false, false, 0);
gain_automation_state_changed ();
@@ -668,7 +672,7 @@ GainMeter::set_fader_name (const char * name)
void
GainMeter::update_gain_sensitive ()
{
- static_cast<Gtkmm2ext::SliderController*>(gain_slider)->set_sensitive (!(_io->gain_automation_state() & Play));
+ static_cast<Gtkmm2ext::SliderController*>(gain_slider)->set_sensitive (!(_io->gain_automation().automation_state() & Play));
}
@@ -811,14 +815,14 @@ GainMeter::meter_point_clicked ()
gint
GainMeter::start_gain_touch (GdkEventButton* ev)
{
- _io->start_gain_touch ();
+ _io->gain_automation().start_touch ();
return FALSE;
}
gint
GainMeter::end_gain_touch (GdkEventButton* ev)
{
- _io->end_gain_touch ();
+ _io->gain_automation().stop_touch ();
return FALSE;
}
@@ -922,10 +926,10 @@ GainMeter::gain_automation_style_changed ()
// Route* _route = dynamic_cast<Route*>(&_io);
switch (_width) {
case Wide:
- gain_automation_style_button.set_label (astyle_string(_io->gain_automation_curve().automation_style()));
+ gain_automation_style_button.set_label (astyle_string(_io->gain_automation().automation_style()));
break;
case Narrow:
- gain_automation_style_button.set_label (short_astyle_string(_io->gain_automation_curve().automation_style()));
+ gain_automation_style_button.set_label (short_astyle_string(_io->gain_automation().automation_style()));
break;
}
}
@@ -940,14 +944,14 @@ GainMeter::gain_automation_state_changed ()
switch (_width) {
case Wide:
- gain_automation_state_button.set_label (astate_string(_io->gain_automation_curve().automation_state()));
+ gain_automation_state_button.set_label (astate_string(_io->gain_automation().automation_state()));
break;
case Narrow:
- gain_automation_state_button.set_label (short_astate_string(_io->gain_automation_curve().automation_state()));
+ gain_automation_state_button.set_label (short_astate_string(_io->gain_automation().automation_state()));
break;
}
- x = (_io->gain_automation_state() != Off);
+ x = (_io->gain_automation().automation_state() != Off);
if (gain_automation_state_button.get_active() != x) {
ignore_toggle = true;
diff --git a/gtk2_ardour/ladspa_pluginui.cc b/gtk2_ardour/ladspa_pluginui.cc
index cd585d073a..25c497a377 100644
--- a/gtk2_ardour/ladspa_pluginui.cc
+++ b/gtk2_ardour/ladspa_pluginui.cc
@@ -177,7 +177,7 @@ LadspaPluginUI::build ()
/* Don't show latency control ports */
- if (plugin->describe_parameter (i) == X_("latency")) {
+ if (plugin->describe_parameter (ParamID(PluginAutomation, i)) == X_("latency")) {
continue;
}
@@ -324,7 +324,8 @@ LadspaPluginUI::automation_state_changed (ControlUI* cui)
{
/* update button label */
- switch (insert->get_port_automation_state (cui->port_index) & (Off|Play|Touch|Write)) {
+ switch (insert->get_parameter_automation_state (ParamID(PluginAutomation, cui->port_index))
+ & (Off|Play|Touch|Write)) {
case Off:
cui->automate_button.set_label (_("Manual"));
break;
@@ -491,7 +492,7 @@ LadspaPluginUI::build_control_ui (guint32 port_index, PBD::Controllable* mcontro
automation_state_changed (control_ui);
plugin->ParameterChanged.connect (bind (mem_fun(*this, &LadspaPluginUI::parameter_changed), control_ui));
- insert->automation_list (port_index).automation_state_changed.connect
+ insert->automation_list (ParamID(PluginAutomation, port_index))->automation_state_changed.connect
(bind (mem_fun(*this, &LadspaPluginUI::automation_state_changed), control_ui));
} else if (plugin->parameter_is_output (port_index)) {
@@ -548,13 +549,13 @@ LadspaPluginUI::build_control_ui (guint32 port_index, PBD::Controllable* mcontro
void
LadspaPluginUI::start_touch (LadspaPluginUI::ControlUI* cui)
{
- insert->automation_list (cui->port_index).start_touch ();
+ insert->automation_list (ParamID(PluginAutomation, cui->port_index))->start_touch ();
}
void
LadspaPluginUI::stop_touch (LadspaPluginUI::ControlUI* cui)
{
- insert->automation_list (cui->port_index).stop_touch ();
+ insert->automation_list (ParamID(PluginAutomation, cui->port_index))->stop_touch ();
}
void
@@ -585,7 +586,7 @@ LadspaPluginUI::astate_clicked (ControlUI* cui, uint32_t port)
void
LadspaPluginUI::set_automation_state (AutoState state, ControlUI* cui)
{
- insert->set_port_automation_state (cui->port_index, state);
+ insert->set_parameter_automation_state (ParamID(PluginAutomation, cui->port_index), state);
}
void
@@ -601,7 +602,7 @@ LadspaPluginUI::control_adjustment_changed (ControlUI* cui)
value = exp(value);
}
- insert->set_parameter (cui->port_index, (float) value);
+ insert->set_parameter (ParamID(PluginAutomation, cui->port_index), (float) value);
}
void
@@ -656,7 +657,7 @@ void
LadspaPluginUI::control_port_toggled (ControlUI* cui)
{
if (!cui->ignore_change) {
- insert->set_parameter (cui->port_index, cui->button->get_active());
+ insert->set_parameter (ParamID(PluginAutomation, cui->port_index), cui->button->get_active());
}
}
@@ -666,7 +667,7 @@ LadspaPluginUI::control_combo_changed (ControlUI* cui)
if (!cui->ignore_change) {
string value = cui->combo->get_active_text();
std::map<string,float> mapping = *cui->combo_map;
- insert->set_parameter (cui->port_index, mapping[value]);
+ insert->set_parameter (ParamID(PluginAutomation, cui->port_index), mapping[value]);
}
}
diff --git a/gtk2_ardour/midi_controller_time_axis.cc b/gtk2_ardour/midi_controller_time_axis.cc
new file mode 100644
index 0000000000..a3dcb0f508
--- /dev/null
+++ b/gtk2_ardour/midi_controller_time_axis.cc
@@ -0,0 +1,81 @@
+/*
+ Copyright (C) 2003 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <ardour/automation_event.h>
+#include <ardour/route.h>
+#include <pbd/memento_command.h>
+
+#include "midi_controller_time_axis.h"
+#include "automation_line.h"
+#include "canvas.h"
+
+#include "i18n.h"
+
+using namespace ARDOUR;
+using namespace PBD;
+using namespace Gtk;
+
+MidiControllerTimeAxisView::MidiControllerTimeAxisView (Session& s, boost::shared_ptr<Route> r,
+ PublicEditor& e, TimeAxisView& parent,
+ ArdourCanvas::Canvas& canvas, const string & n,
+ ParamID param, ARDOUR::AutomationList& l)
+
+ : AxisView (s),
+ AutomationTimeAxisView (s, r, e, parent, canvas, n, param.to_string(), ""),
+ _list (l),
+ _param (param)
+{
+}
+
+MidiControllerTimeAxisView::~MidiControllerTimeAxisView ()
+{
+}
+
+void
+MidiControllerTimeAxisView::add_automation_event (ArdourCanvas::Item* item, GdkEvent* event, nframes_t when, double y)
+{
+ double x = 0;
+
+ canvas_display->w2i (x, y);
+
+ /* compute vertical fractional position */
+
+ y = 1.0 - (y / height);
+
+ /* map using line */
+
+ lines.front()->view_to_model_y (y);
+
+ _session.begin_reversible_command (_("add midi controller automation event"));
+ XMLNode& before = _list.get_state();
+ _list.add (when, y);
+ XMLNode& after = _list.get_state();
+ _session.commit_reversible_command (new MementoCommand<ARDOUR::AutomationList>(_list, &before, &after));
+ _session.set_dirty ();
+}
+
+void
+MidiControllerTimeAxisView::set_automation_state (AutoState state)
+{
+ if (!ignore_state_request) {
+ cerr << "FIXME: set midi controller automation state" << endl;
+ //route->set_midi_controller_state (state);
+ }
+}
+
diff --git a/gtk2_ardour/midi_controller_time_axis.h b/gtk2_ardour/midi_controller_time_axis.h
new file mode 100644
index 0000000000..78f3c12c1a
--- /dev/null
+++ b/gtk2_ardour/midi_controller_time_axis.h
@@ -0,0 +1,54 @@
+/*
+ Copyright (C) 2000-2007 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef __ardour_gtk_midi_controller_time_axis_h__
+#define __ardour_gtk_midi_controller_time_axis_h__
+
+#include "canvas.h"
+#include "automation_time_axis.h"
+
+namespace ARDOUR {
+ class AutomationList;
+}
+
+class MidiControllerTimeAxisView : public AutomationTimeAxisView
+{
+ public:
+ MidiControllerTimeAxisView (ARDOUR::Session&,
+ boost::shared_ptr<ARDOUR::Route>,
+ PublicEditor&,
+ TimeAxisView& parent_axis,
+ ArdourCanvas::Canvas& canvas,
+ const string & name,
+ ARDOUR::ParamID param,
+ ARDOUR::AutomationList&);
+
+ ~MidiControllerTimeAxisView();
+
+ void add_automation_event (ArdourCanvas::Item *item, GdkEvent *event, nframes_t, double);
+
+ private:
+ ARDOUR::AutomationList& _list;
+ ARDOUR::ParamID _param;
+
+ void automation_changed ();
+ void set_automation_state (ARDOUR::AutoState);
+};
+
+#endif /* __ardour_gtk_midi_controller_time_axis_h__ */
diff --git a/gtk2_ardour/midi_time_axis.cc b/gtk2_ardour/midi_time_axis.cc
index dd008bd9c5..960ca36af9 100644
--- a/gtk2_ardour/midi_time_axis.cc
+++ b/gtk2_ardour/midi_time_axis.cc
@@ -48,6 +48,7 @@
#include "ardour_ui.h"
#include "midi_time_axis.h"
#include "automation_time_axis.h"
+#include "automation_midi_cc_line.h"
#include "canvas_impl.h"
#include "crossfade_view.h"
#include "enums.h"
@@ -61,6 +62,7 @@
#include "public_editor.h"
#include "redirect_automation_line.h"
#include "redirect_automation_time_axis.h"
+#include "midi_controller_time_axis.h"
#include "region_view.h"
#include "rgb_macros.h"
#include "selection.h"
@@ -147,30 +149,67 @@ MidiTimeAxisView::hide ()
}
void
-MidiTimeAxisView::set_state (const XMLNode& node)
+MidiTimeAxisView::build_automation_action_menu ()
{
- const XMLProperty *prop;
+ using namespace Menu_Helpers;
+
+ RouteTimeAxisView::build_automation_action_menu ();
+
+ MenuList& automation_items = automation_action_menu->items();
- TimeAxisView::set_state (node);
+ automation_items.push_back (SeparatorElem());
+
+ automation_items.push_back (MenuElem (_("Controller..."),
+ mem_fun(*this, &MidiTimeAxisView::add_controller_track)));
+}
+
+/** Prompt for a controller with a dialog and add an automation track for it
+ */
+void
+MidiTimeAxisView::add_controller_track()
+{
+ /* TODO: fancy controller selection dialog here... */
+
+ ParamID param(MidiCCAutomation, 7);
+ create_automation_child(param);
+}
+
+void
+MidiTimeAxisView::create_automation_child (ParamID param)
+{
+ if (param.type() == MidiCCAutomation) {
- if ((prop = node.property ("shown_editor")) != 0) {
- if (prop->value() == "no") {
- _marked_for_display = false;
- } else {
- _marked_for_display = true;
- }
+ /* FIXME: this all probably leaks */
+
+ ARDOUR::AutomationList* al = _route->automation_list(param);
+
+ if (!al)
+ al = new ARDOUR::AutomationList(param, 0, 127, 64);
+
+ _route->add_automation_parameter(al);
+
+ MidiControllerTimeAxisView* track = new MidiControllerTimeAxisView (_session,
+ _route,
+ editor,
+ *this,
+ parent_canvas,
+ _route->describe_parameter(param),
+ param,
+ *al);
+
+ AutomationMidiCCLine* line = new AutomationMidiCCLine (param.to_string(),
+ *track,
+ *track->canvas_display,
+ *al);
+
+ line->set_line_color (Config->canvasvar_AutomationLine.get());
+
+ track->add_line(*line);
+
+ add_automation_child(param, track);
+
} else {
- _marked_for_display = true;
- }
-
- XMLNodeList nlist = node.children();
- XMLNodeConstIterator niter;
- XMLNode *child_node;
-
- for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
- child_node = *niter;
-
- // uh... do stuff..
+ error << "MidiTimeAxisView: unknown automation child " << param.to_string() << endmsg;
}
}
@@ -205,9 +244,3 @@ MidiTimeAxisView::route_active_changed ()
}
}
-XMLNode*
-MidiTimeAxisView::get_child_xml_node (const string & childname)
-{
- return RouteUI::get_child_xml_node (childname);
-}
-
diff --git a/gtk2_ardour/midi_time_axis.h b/gtk2_ardour/midi_time_axis.h
index 17b3d72794..3b06411418 100644
--- a/gtk2_ardour/midi_time_axis.h
+++ b/gtk2_ardour/midi_time_axis.h
@@ -61,11 +61,14 @@ class MidiTimeAxisView : public RouteTimeAxisView
/* overridden from parent to store display state */
guint32 show_at (double y, int& nth, Gtk::VBox *parent);
void hide ();
-
- void set_state (const XMLNode&);
- XMLNode* get_child_xml_node (const string & childname);
+
+ void add_controller_track ();
+ void create_automation_child (ARDOUR::ParamID param);
private:
+
+ void build_automation_action_menu ();
+
void route_active_changed ();
void add_insert_to_subplugin_menu (ARDOUR::Insert *);
diff --git a/gtk2_ardour/mixer_strip.cc b/gtk2_ardour/mixer_strip.cc
index 0c99dc7401..cb27ef4e88 100644
--- a/gtk2_ardour/mixer_strip.cc
+++ b/gtk2_ardour/mixer_strip.cc
@@ -435,8 +435,8 @@ MixerStrip::set_width (Width w, void* owner)
((Gtk::Label*)comment_button.get_child())->set_text (_("*comments*"));
}
- ((Gtk::Label*)gpm.gain_automation_style_button.get_child())->set_text (gpm.astyle_string(_route->gain_automation_curve().automation_style()));
- ((Gtk::Label*)gpm.gain_automation_state_button.get_child())->set_text (gpm.astate_string(_route->gain_automation_curve().automation_state()));
+ ((Gtk::Label*)gpm.gain_automation_style_button.get_child())->set_text (gpm.astyle_string(_route->gain_automation().automation_style()));
+ ((Gtk::Label*)gpm.gain_automation_state_button.get_child())->set_text (gpm.astate_string(_route->gain_automation().automation_state()));
((Gtk::Label*)panners.pan_automation_style_button.get_child())->set_text (panners.astyle_string(_route->panner().automation_style()));
((Gtk::Label*)panners.pan_automation_state_button.get_child())->set_text (panners.astate_string(_route->panner().automation_state()));
Gtkmm2ext::set_size_request_to_display_given_text (name_button, "long", 2, 2);
@@ -457,8 +457,8 @@ MixerStrip::set_width (Width w, void* owner)
((Gtk::Label*)comment_button.get_child())->set_text (_("*Cmt*"));
}
- ((Gtk::Label*)gpm.gain_automation_style_button.get_child())->set_text (gpm.short_astyle_string(_route->gain_automation_curve().automation_style()));
- ((Gtk::Label*)gpm.gain_automation_state_button.get_child())->set_text (gpm.short_astate_string(_route->gain_automation_curve().automation_state()));
+ ((Gtk::Label*)gpm.gain_automation_style_button.get_child())->set_text (gpm.short_astyle_string(_route->gain_automation().automation_style()));
+ ((Gtk::Label*)gpm.gain_automation_state_button.get_child())->set_text (gpm.short_astate_string(_route->gain_automation().automation_state()));
((Gtk::Label*)panners.pan_automation_style_button.get_child())->set_text (panners.short_astyle_string(_route->panner().automation_style()));
((Gtk::Label*)panners.pan_automation_state_button.get_child())->set_text (panners.short_astate_string(_route->panner().automation_state()));
Gtkmm2ext::set_size_request_to_display_given_text (name_button, "longest label", 2, 2);
diff --git a/gtk2_ardour/pan_automation_time_axis.cc b/gtk2_ardour/pan_automation_time_axis.cc
index c008a10ff0..1199982b5d 100644
--- a/gtk2_ardour/pan_automation_time_axis.cc
+++ b/gtk2_ardour/pan_automation_time_axis.cc
@@ -55,6 +55,11 @@ PanAutomationTimeAxisView::add_automation_event (ArdourCanvas::Item* item, GdkEv
{
if (lines.empty()) {
/* no data, possibly caused by no outputs/inputs */
+ Gtkmm2ext::PopUp* msg = new Gtkmm2ext::PopUp (Gtk::WIN_POS_MOUSE, 5000, true);
+
+ msg->set_text (_("Pan automation track has no lines, unable to add point\n(is track pannable?)"));
+ msg->touch ();
+
return;
}
diff --git a/gtk2_ardour/plugin_ui.h b/gtk2_ardour/plugin_ui.h
index a505f80576..e583f11dce 100644
--- a/gtk2_ardour/plugin_ui.h
+++ b/gtk2_ardour/plugin_ui.h
@@ -136,6 +136,10 @@ class LadspaPluginUI : public PlugUIBase, public Gtk::VBox
static const int32_t initial_output_rows = 1;
static const int32_t initial_output_cols = 4;
+ /* TODO: pull this out of PluginUI and make it generic.
+ * Sticking this in the track controls of an automation track would
+ * make a handy touch controller for anything.
+ */
struct ControlUI : public Gtk::HBox {
uint32_t port_index;
diff --git a/gtk2_ardour/redirect_automation_line.cc b/gtk2_ardour/redirect_automation_line.cc
index 89b6fb4f2a..5680a8b98f 100644
--- a/gtk2_ardour/redirect_automation_line.cc
+++ b/gtk2_ardour/redirect_automation_line.cc
@@ -33,7 +33,7 @@ using namespace std;
using namespace ARDOUR;
using namespace PBD;
-RedirectAutomationLine::RedirectAutomationLine (const string & name, Insert& i, uint32_t port, Session& s,
+RedirectAutomationLine::RedirectAutomationLine (const string & name, Insert& i, ParamID param, Session& s,
TimeAxisView& tv, ArdourCanvas::Group& parent,
@@ -42,7 +42,7 @@ RedirectAutomationLine::RedirectAutomationLine (const string & name, Insert& i,
: AutomationLine (name, tv, parent, l),
session (s),
_insert (i),
- _port (port)
+ _param (param)
{
set_verbose_cursor_uses_gain_mapping (false);
@@ -54,7 +54,7 @@ RedirectAutomationLine::RedirectAutomationLine (const string & name, Insert& i,
/*NOTREACHED*/
}
- pi->plugin()->get_parameter_descriptor (_port, desc);
+ pi->plugin()->get_parameter_descriptor (_param, desc);
upper = desc.upper;
lower = desc.lower;
diff --git a/gtk2_ardour/redirect_automation_line.h b/gtk2_ardour/redirect_automation_line.h
index 33d411e48e..d0e3aa8897 100644
--- a/gtk2_ardour/redirect_automation_line.h
+++ b/gtk2_ardour/redirect_automation_line.h
@@ -34,10 +34,10 @@ class TimeAxisView;
class RedirectAutomationLine : public AutomationLine
{
public:
- RedirectAutomationLine (const string & name, ARDOUR::Insert&, uint32_t port, ARDOUR::Session&, TimeAxisView&,
+ RedirectAutomationLine (const string & name, ARDOUR::Insert&, ARDOUR::ParamID param, ARDOUR::Session&, TimeAxisView&,
ArdourCanvas::Group& parent, ARDOUR::AutomationList&);
- uint32_t port() const { return _port; }
+ ARDOUR::ParamID param() const { return _param; }
ARDOUR::Insert& insert() const { return _insert; }
string get_verbose_cursor_string (float);
@@ -45,7 +45,7 @@ class RedirectAutomationLine : public AutomationLine
private:
ARDOUR::Session& session;
ARDOUR::Insert& _insert;
- uint32_t _port;
+ ARDOUR::ParamID _param;
float upper;
float lower;
float range;
diff --git a/gtk2_ardour/redirect_automation_time_axis.cc b/gtk2_ardour/redirect_automation_time_axis.cc
index 9df0bb9e0c..bb7937cdf7 100644
--- a/gtk2_ardour/redirect_automation_time_axis.cc
+++ b/gtk2_ardour/redirect_automation_time_axis.cc
@@ -34,12 +34,12 @@ using namespace Gtk;
RedirectAutomationTimeAxisView::RedirectAutomationTimeAxisView (Session& s, boost::shared_ptr<Route> r,
PublicEditor& e, TimeAxisView& parent, Canvas& canvas, std::string n,
- uint32_t prt, Insert& i, string state_name)
+ ParamID p, Insert& i, string state_name)
: AxisView (s),
AutomationTimeAxisView (s, r, e, parent, canvas, n, state_name, i.name()),
insert (i),
- port (prt)
+ param (p)
{
char buf[32];
@@ -53,7 +53,7 @@ RedirectAutomationTimeAxisView::RedirectAutomationTimeAxisView (Session& s, boos
kids = xml_node->children ();
- snprintf (buf, sizeof(buf), "Port_%" PRIu32, port);
+ snprintf (buf, sizeof(buf), "Port_%" PRIu32, param.id());
for (iter = kids.begin(); iter != kids.end(); ++iter) {
if ((*iter)->name() == buf) {
@@ -91,17 +91,17 @@ RedirectAutomationTimeAxisView::add_automation_event (ArdourCanvas::Item* item,
/* map to model space */
if (!lines.empty()) {
- AutomationList& alist (insert.automation_list(port));
+ AutomationList* alist (insert.automation_list(param, true));
string description = _("add automation event to ");
- description += insert.describe_parameter (port);
+ description += insert.describe_parameter (param);
lines.front()->view_to_model_y (y);
_session.begin_reversible_command (description);
- XMLNode &before = alist.get_state();
- alist.add (when, y);
- XMLNode &after = alist.get_state();
- _session.add_command(new MementoCommand<AutomationList>(alist, &before, &after));
+ XMLNode &before = alist->get_state();
+ alist->add (when, y);
+ XMLNode &after = alist->get_state();
+ _session.add_command(new MementoCommand<AutomationList>(*alist, &before, &after));
_session.commit_reversible_command ();
_session.set_dirty ();
}
@@ -146,7 +146,7 @@ RedirectAutomationTimeAxisView::update_extra_xml_shown (bool editor_shown)
XMLNodeConstIterator i;
XMLNode * port_node = 0;
- snprintf (buf, sizeof(buf), "Port_%" PRIu32, port);
+ snprintf (buf, sizeof(buf), "Port_%" PRIu32, param.id());
for (i = nlist.begin(); i != nlist.end(); ++i) {
if ((*i)->name() == buf) {
@@ -168,6 +168,6 @@ void
RedirectAutomationTimeAxisView::set_automation_state (AutoState state)
{
if (!ignore_state_request) {
- insert.automation_list (port).set_automation_state (state);
+ insert.automation_list (param, true)->set_automation_state (state);
}
}
diff --git a/gtk2_ardour/redirect_automation_time_axis.h b/gtk2_ardour/redirect_automation_time_axis.h
index eceed7446a..d87e4faca5 100644
--- a/gtk2_ardour/redirect_automation_time_axis.h
+++ b/gtk2_ardour/redirect_automation_time_axis.h
@@ -24,6 +24,7 @@
#include "canvas.h"
#include "automation_time_axis.h"
+#include <ardour/param_id.h>
namespace ARDOUR {
class Redirect;
@@ -38,7 +39,7 @@ class RedirectAutomationTimeAxisView : public AutomationTimeAxisView
TimeAxisView& parent,
ArdourCanvas::Canvas& canvas,
std::string name,
- uint32_t port,
+ ARDOUR::ParamID param,
ARDOUR::Insert& i,
std::string state_name);
@@ -52,7 +53,7 @@ class RedirectAutomationTimeAxisView : public AutomationTimeAxisView
private:
ARDOUR::Insert& insert;
- uint32_t port;
+ ARDOUR::ParamID param;
XMLNode *xml_node;
void ensure_xml_node();
diff --git a/gtk2_ardour/redirect_box.cc b/gtk2_ardour/redirect_box.cc
index 8749ab12db..0402b0e1f6 100644
--- a/gtk2_ardour/redirect_box.cc
+++ b/gtk2_ardour/redirect_box.cc
@@ -1050,7 +1050,7 @@ RedirectBox::edit_insert (boost::shared_ptr<Insert> insert)
}
}
- if ((send = boost::dynamic_pointer_cast<Send> (send)) == 0) {
+ if ((send = boost::dynamic_pointer_cast<Send> (send)) != 0) {
if (!_session.engine().connected()) {
return;
diff --git a/gtk2_ardour/region_gain_line.cc b/gtk2_ardour/region_gain_line.cc
index e935d3adc2..25ba903ca8 100644
--- a/gtk2_ardour/region_gain_line.cc
+++ b/gtk2_ardour/region_gain_line.cc
@@ -38,8 +38,8 @@ using namespace std;
using namespace ARDOUR;
using namespace PBD;
-AudioRegionGainLine::AudioRegionGainLine (const string & name, Session& s, AudioRegionView& r, ArdourCanvas::Group& parent, Curve& c)
- : AutomationLine (name, r.get_time_axis_view(), parent, c),
+AudioRegionGainLine::AudioRegionGainLine (const string & name, Session& s, AudioRegionView& r, ArdourCanvas::Group& parent, AutomationList& l)
+ : AutomationLine (name, r.get_time_axis_view(), parent, l),
session (s),
rv (r)
{
diff --git a/gtk2_ardour/region_gain_line.h b/gtk2_ardour/region_gain_line.h
index 801fe09bad..259615aa39 100644
--- a/gtk2_ardour/region_gain_line.h
+++ b/gtk2_ardour/region_gain_line.h
@@ -35,7 +35,7 @@ class AudioRegionView;
class AudioRegionGainLine : public AutomationLine
{
public:
- AudioRegionGainLine (const string & name, ARDOUR::Session&, AudioRegionView&, ArdourCanvas::Group& parent, ARDOUR::Curve&);
+ AudioRegionGainLine (const string & name, ARDOUR::Session&, AudioRegionView&, ArdourCanvas::Group& parent, ARDOUR::AutomationList&);
void view_to_model_y (double&);
void model_to_view_y (double&);
diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc
index 900064a763..f113724cf5 100644
--- a/gtk2_ardour/route_time_axis.cc
+++ b/gtk2_ardour/route_time_axis.cc
@@ -23,6 +23,7 @@
#include <algorithm>
#include <string>
#include <vector>
+#include <utility>
#include <sigc++/bind.h>
@@ -50,6 +51,7 @@
#include <ardour/session.h>
#include <ardour/session_playlist.h>
#include <ardour/utils.h>
+#include <ardour/param_id.h>
#include "ardour_ui.h"
#include "route_time_axis.h"
@@ -80,6 +82,7 @@ using namespace ARDOUR;
using namespace PBD;
using namespace Gtk;
using namespace Editing;
+using namespace sigc;
RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session& sess, boost::shared_ptr<Route> rt, Canvas& canvas)
@@ -252,6 +255,58 @@ RouteTimeAxisView::playlist_modified ()
{
}
+void
+RouteTimeAxisView::set_state (const XMLNode& node)
+{
+ const XMLProperty *prop;
+
+ TimeAxisView::set_state (node);
+
+ if ((prop = node.property ("shown_editor")) != 0) {
+ if (prop->value() == "no") {
+ _marked_for_display = false;
+ } else {
+ _marked_for_display = true;
+ }
+ } else {
+ _marked_for_display = true;
+ }
+
+ XMLNodeList nlist = node.children();
+ XMLNodeConstIterator niter;
+ XMLNode *child_node;
+
+ _show_automation.clear();
+
+ for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
+ child_node = *niter;
+
+ ParamID param(child_node->name());
+
+ if (param) {
+
+ cerr << "RTAV::set_state parameter: " << param.to_string() << endl;
+
+ XMLProperty* prop = child_node->property ("shown");
+
+ if (_automation_tracks.find(param) == _automation_tracks.end())
+ create_automation_child(param);
+
+ if (prop != 0 && prop->value() == "yes")
+ _show_automation.insert(ParamID(GainAutomation));
+
+ } else {
+ cerr << "RTAV: no parameter " << child_node->name() << endl;
+ }
+ }
+}
+
+XMLNode*
+RouteTimeAxisView::get_child_xml_node (const string & childname)
+{
+ return RouteUI::get_child_xml_node (childname);
+}
+
gint
RouteTimeAxisView::edit_click (GdkEventButton *ev)
{
@@ -386,6 +441,24 @@ RouteTimeAxisView::build_automation_action_menu ()
mem_fun(*this, &RouteTimeAxisView::hide_all_automation)));
automation_items.push_back (MenuElem (_("Plugins"), subplugin_menu));
+
+ map<ARDOUR::ParamID, RouteAutomationNode*>::iterator i;
+ for (i = _automation_tracks.begin(); i != _automation_tracks.end(); ++i) {
+
+ automation_items.push_back (SeparatorElem());
+
+ if ( ! i->second->menu_item) {
+ automation_items.push_back(CheckMenuElem (_route->describe_parameter(i->second->param),
+ bind (mem_fun(*this, &RouteTimeAxisView::toggle_automation_track), i->second->param)));
+
+ i->second->menu_item = static_cast<Gtk::CheckMenuItem*>(&automation_items.back());
+
+ } else {
+ automation_items.push_back (*i->second->menu_item);
+ }
+
+ i->second->menu_item->set_active(show_automation(i->second->param));
+ }
}
void
@@ -1092,6 +1165,33 @@ RouteTimeAxisView::get_inverted_selectables (Selection& sel, list<Selectable*>&
return;
}
+bool
+RouteTimeAxisView::show_automation(ParamID param)
+{
+ return (_show_automation.find(param) != _show_automation.end());
+}
+
+/** Retuns NULL if track for \a param doesn't exist.
+ */
+RouteTimeAxisView::RouteAutomationNode*
+RouteTimeAxisView::automation_track(ParamID param)
+{
+ map<ARDOUR::ParamID, RouteAutomationNode*>::iterator i = _automation_tracks.find(param);
+
+ if (i != _automation_tracks.end())
+ return i->second;
+ else
+ return NULL;
+}
+
+/** Shorthand for GainAutomation, etc.
+ */
+RouteTimeAxisView::RouteAutomationNode*
+RouteTimeAxisView::automation_track(AutomationType type)
+{
+ return automation_track(ParamID(type));
+}
+
RouteGroup*
RouteTimeAxisView::edit_group() const
{
@@ -1380,9 +1480,69 @@ RouteTimeAxisView::color_handler ()
}
void
+RouteTimeAxisView::toggle_automation_track (ParamID param)
+{
+ RouteAutomationNode* node = automation_track(param);
+
+ if (!node)
+ return;
+
+ bool showit = node->menu_item->get_active();
+
+ if (showit != node->track->marked_for_display()) {
+ if (showit) {
+ node->track->set_marked_for_display (true);
+ node->track->canvas_display->show();
+ node->track->get_state_node()->add_property ("shown", X_("yes"));
+ } else {
+ node->track->set_marked_for_display (false);
+ node->track->hide ();
+ node->track->get_state_node()->add_property ("shown", X_("no"));
+ }
+
+ /* now trigger a redisplay */
+
+ if (!no_redraw) {
+ _route->gui_changed (X_("track_height"), (void *) 0); /* EMIT_SIGNAL */
+ }
+ }
+}
+
+void
+RouteTimeAxisView::automation_track_hidden (ParamID param)
+{
+ RouteAutomationNode* ran = automation_track(param);
+ if (!ran)
+ return;
+
+ _show_automation.erase(param);
+ ran->track->get_state_node()->add_property (X_("shown"), X_("no"));
+
+ if (ran->menu_item && !_hidden) {
+ ran->menu_item->set_active (false);
+ }
+
+ _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
+}
+
+
+void
RouteTimeAxisView::show_all_automation ()
{
no_redraw = true;
+
+ /* Show our automation */
+
+ map<ARDOUR::ParamID, RouteAutomationNode*>::iterator i;
+ for (i = _automation_tracks.begin(); i != _automation_tracks.end(); ++i) {
+ i->second->track->set_marked_for_display (true);
+ i->second->track->canvas_display->show();
+ i->second->track->get_state_node()->add_property ("shown", X_("yes"));
+ i->second->menu_item->set_active(true);
+ }
+
+
+ /* Show insert automation */
for (list<InsertAutomationInfo*>::iterator i = insert_automation.begin(); i != insert_automation.end(); ++i) {
for (vector<InsertAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) {
@@ -1396,6 +1556,9 @@ RouteTimeAxisView::show_all_automation ()
no_redraw = false;
+
+ /* Redraw */
+
_route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
}
@@ -1403,6 +1566,22 @@ void
RouteTimeAxisView::show_existing_automation ()
{
no_redraw = true;
+
+ /* Show our automation */
+
+ map<ARDOUR::ParamID, RouteAutomationNode*>::iterator i;
+ for (i = _automation_tracks.begin(); i != _automation_tracks.end(); ++i) {
+ // FIXME: only shown if /first/ line has points
+ if (!i->second->track->lines.empty() && i->second->track->lines[0]->npoints() > 0) {
+ i->second->track->set_marked_for_display (true);
+ i->second->track->canvas_display->show();
+ i->second->track->get_state_node()->add_property ("shown", X_("yes"));
+ i->second->menu_item->set_active(true);
+ }
+ }
+
+
+ /* Show insert automation */
for (list<InsertAutomationInfo*>::iterator i = insert_automation.begin(); i != insert_automation.end(); ++i) {
for (vector<InsertAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) {
@@ -1477,7 +1656,7 @@ RouteTimeAxisView::remove_ran (InsertAutomationNode* ran)
}
RouteTimeAxisView::InsertAutomationNode*
-RouteTimeAxisView::find_insert_automation_node (boost::shared_ptr<Insert> insert, uint32_t what)
+RouteTimeAxisView::find_insert_automation_node (boost::shared_ptr<Insert> insert, ParamID what)
{
for (list<InsertAutomationInfo*>::iterator i = insert_automation.begin(); i != insert_automation.end(); ++i) {
@@ -1514,7 +1693,7 @@ legalize_for_xml_node (string str)
void
-RouteTimeAxisView::add_insert_automation_curve (boost::shared_ptr<Insert> insert, uint32_t what)
+RouteTimeAxisView::add_insert_automation_curve (boost::shared_ptr<Insert> insert, ParamID what)
{
RedirectAutomationLine* ral;
string name;
@@ -1538,13 +1717,13 @@ RouteTimeAxisView::add_insert_automation_curve (boost::shared_ptr<Insert> insert
/* create a string that is a legal XML node name that can be used to refer to this redirect+port combination */
char state_name[256];
- snprintf (state_name, sizeof (state_name), "Redirect-%s-%" PRIu32, legalize_for_xml_node (insert->name()).c_str(), what);
+ snprintf (state_name, sizeof (state_name), "Redirect-%s-%" PRIu32, legalize_for_xml_node (insert->name()).c_str(), what.id());
ran->view = new RedirectAutomationTimeAxisView (_session, _route, editor, *this, parent_canvas, name, what, *insert, state_name);
ral = new RedirectAutomationLine (name,
*insert, what, _session, *ran->view,
- *ran->view->canvas_display, insert->automation_list (what));
+ *ran->view->canvas_display, *insert->automation_list (what, true));
ral->set_line_color (Config->canvasvar_RedirectAutomationLine.get());
ral->queue_reset ();
@@ -1583,12 +1762,12 @@ RouteTimeAxisView::insert_automation_track_hidden (RouteTimeAxisView::InsertAuto
void
RouteTimeAxisView::add_existing_insert_automation_curves (boost::shared_ptr<Insert> insert)
{
- set<uint32_t> s;
+ set<ParamID> s;
RedirectAutomationLine *ral;
insert->what_has_visible_automation (s);
- for (set<uint32_t>::iterator i = s.begin(); i != s.end(); ++i) {
+ for (set<ParamID>::iterator i = s.begin(); i != s.end(); ++i) {
if ((ral = find_insert_automation_curve (insert, *i)) != 0) {
ral->queue_reset ();
@@ -1599,14 +1778,47 @@ RouteTimeAxisView::add_existing_insert_automation_curves (boost::shared_ptr<Inse
}
void
+RouteTimeAxisView::add_automation_child(ParamID param, AutomationTimeAxisView* track)
+{
+ using namespace Menu_Helpers;
+
+ XMLProperty* prop;
+
+ add_child (track);
+
+ track->Hiding.connect (bind (mem_fun (*this, &RouteTimeAxisView::automation_track_hidden), param));
+
+ bool hideit = true;
+
+ XMLNode* node;
+
+ if ((node = track->get_state_node()) != 0) {
+ if ((prop = node->property ("shown")) != 0) {
+ if (prop->value() == "yes") {
+ hideit = false;
+ }
+ }
+ }
+
+ if (hideit) {
+ track->hide ();
+ } else {
+ _show_automation.insert(param);
+ }
+
+ _automation_tracks.insert(std::make_pair(param, new RouteAutomationNode(param, NULL, track)));
+}
+
+
+void
RouteTimeAxisView::add_insert_to_subplugin_menu (boost::shared_ptr<Insert> insert)
{
using namespace Menu_Helpers;
InsertAutomationInfo *rai;
list<InsertAutomationInfo*>::iterator x;
- const std::set<uint32_t>& automatable = insert->what_can_be_automated ();
- std::set<uint32_t> has_visible_automation;
+ const std::set<ParamID>& automatable = insert->what_can_be_automated ();
+ std::set<ParamID> has_visible_automation;
insert->what_has_visible_automation(has_visible_automation);
@@ -1641,7 +1853,7 @@ RouteTimeAxisView::add_insert_to_subplugin_menu (boost::shared_ptr<Insert> inser
items.clear ();
- for (std::set<uint32_t>::const_iterator i = automatable.begin(); i != automatable.end(); ++i) {
+ for (std::set<ParamID>::const_iterator i = automatable.begin(); i != automatable.end(); ++i) {
InsertAutomationNode* ran;
CheckMenuItem* mitem;
@@ -1755,7 +1967,7 @@ RouteTimeAxisView::inserts_changed ()
}
RedirectAutomationLine *
-RouteTimeAxisView::find_insert_automation_curve (boost::shared_ptr<Insert> insert, uint32_t what)
+RouteTimeAxisView::find_insert_automation_curve (boost::shared_ptr<Insert> insert, ParamID what)
{
InsertAutomationNode* ran;
diff --git a/gtk2_ardour/route_time_axis.h b/gtk2_ardour/route_time_axis.h
index e14d682c83..42c889e16f 100644
--- a/gtk2_ardour/route_time_axis.h
+++ b/gtk2_ardour/route_time_axis.h
@@ -79,6 +79,7 @@ public:
void set_selected_regionviews (RegionSelection&);
void get_selectables (nframes_t start, nframes_t end, double top, double bot, list<Selectable *>&);
void get_inverted_selectables (Selection&, list<Selectable*>&);
+ bool show_automation(ARDOUR::ParamID param);
boost::shared_ptr<ARDOUR::Region> find_next_region (nframes_t pos, ARDOUR::RegionPoint, int32_t dir);
@@ -94,6 +95,8 @@ public:
void clear_playlist ();
void build_playlist_menu (Gtk::Menu *);
+
+ virtual void create_automation_child (ARDOUR::ParamID param) = 0;
string name() const;
StreamView* view() const { return _view; }
@@ -103,13 +106,22 @@ public:
protected:
friend class StreamView;
+ struct RouteAutomationNode {
+ ARDOUR::ParamID param;
+ Gtk::CheckMenuItem* menu_item;
+ AutomationTimeAxisView* track;
+
+ RouteAutomationNode (ARDOUR::ParamID par, Gtk::CheckMenuItem* mi, AutomationTimeAxisView* tr)
+ : param (par), menu_item (mi), track (tr) {}
+ };
+
struct InsertAutomationNode {
- uint32_t what;
+ ARDOUR::ParamID what;
Gtk::CheckMenuItem* menu_item;
AutomationTimeAxisView* view;
RouteTimeAxisView& parent;
- InsertAutomationNode (uint32_t w, Gtk::CheckMenuItem* mitem, RouteTimeAxisView& p)
+ InsertAutomationNode (ARDOUR::ParamID w, Gtk::CheckMenuItem* mitem, RouteTimeAxisView& p)
: what (w), menu_item (mitem), view (0), parent (p) {}
~InsertAutomationNode ();
@@ -143,15 +155,22 @@ protected:
void insert_automation_track_hidden (InsertAutomationNode*,
boost::shared_ptr<ARDOUR::Insert>);
+
+ void automation_track_hidden (ARDOUR::ParamID param);
+
+ RouteAutomationNode* automation_track(ARDOUR::ParamID param);
+ RouteAutomationNode* automation_track(ARDOUR::AutomationType type);
InsertAutomationNode*
- find_insert_automation_node (boost::shared_ptr<ARDOUR::Insert> i, uint32_t);
+ find_insert_automation_node (boost::shared_ptr<ARDOUR::Insert> i, ARDOUR::ParamID);
RedirectAutomationLine*
- find_insert_automation_curve (boost::shared_ptr<ARDOUR::Insert> i, uint32_t);
+ find_insert_automation_curve (boost::shared_ptr<ARDOUR::Insert> i, ARDOUR::ParamID);
- void add_insert_automation_curve (boost::shared_ptr<ARDOUR::Insert> r, uint32_t);
+ void add_insert_automation_curve (boost::shared_ptr<ARDOUR::Insert> r, ARDOUR::ParamID);
void add_existing_insert_automation_curves (boost::shared_ptr<ARDOUR::Insert>);
+
+ void add_automation_child(ARDOUR::ParamID param, AutomationTimeAxisView* track);
void reset_insert_automation_curves ();
@@ -186,6 +205,7 @@ protected:
void rename_current_playlist ();
void automation_click ();
+ void toggle_automation_track (ARDOUR::ParamID param);
virtual void show_all_automation ();
virtual void show_existing_automation ();
virtual void hide_all_automation ();
@@ -204,7 +224,6 @@ protected:
void region_view_added (RegionView*);
void add_ghost_to_insert (RegionView*, AutomationTimeAxisView*);
-
StreamView* _view;
ArdourCanvas::Canvas& parent_canvas;
bool no_redraw;
@@ -238,12 +257,21 @@ protected:
void _set_track_mode (ARDOUR::Track* track, ARDOUR::TrackMode mode, Gtk::RadioMenuItem* reset_item);
void track_mode_changed ();
- list<InsertAutomationInfo*> insert_automation;
+ list<InsertAutomationInfo*> insert_automation;
vector<RedirectAutomationLine*> insert_automation_curves;
+
+ // Set from XML so context menu automation buttons can be correctly initialized
+ set<ARDOUR::ParamID> _show_automation;
+
+ map<ARDOUR::ParamID, RouteAutomationNode*> _automation_tracks;
sigc::connection modified_connection;
void post_construct ();
+
+ void set_state (const XMLNode&);
+
+ XMLNode* get_child_xml_node (const string & childname);
};
#endif /* __ardour_route_time_axis_h__ */