A few fixes to interpolation of MIDI controller data. Don't interpolate
[ardour.git] / gtk2_ardour / automation_time_axis.cc
index d2b43d33f925aa1fc8c2e87727ffc367a66e95d6..a7114f8ff0ece3bea569cd8a5d4df8832b5cd600 100644 (file)
@@ -272,6 +272,11 @@ AutomationTimeAxisView::set_automation_state (AutoState state)
 
        if (_view) {
                _view->set_automation_state (state);
+
+               /* AutomationStreamViews don't signal when their automation state changes, so handle
+                  our updates `manually'.
+               */
+               automation_state_changed ();
        }
 }
 
@@ -282,10 +287,12 @@ AutomationTimeAxisView::automation_state_changed ()
 
        /* update button label */
 
-       if (!_line) {
-               state = Off;
-       } else {
+       if (_line) {
                state = _control->alist()->automation_state ();
+       } else if (_view) {
+               state = _view->automation_state ();
+       } else {
+               state = Off;
        }
 
        switch (state & (Off|Play|Touch|Write)) {
@@ -339,13 +346,12 @@ AutomationTimeAxisView::automation_state_changed ()
        }
 }
 
+/** The interpolation style of our AutomationList has changed, so update */
 void
-AutomationTimeAxisView::interpolation_changed ()
+AutomationTimeAxisView::interpolation_changed (AutomationList::InterpolationStyle s)
 {
-       AutomationList::InterpolationStyle style = _control->list()->interpolation();
-
        if (mode_line_item && mode_discrete_item) {
-               if (style == AutomationList::Discrete) {
+               if (s == AutomationList::Discrete) {
                        mode_discrete_item->set_active(true);
                        mode_line_item->set_active(false);
                } else {
@@ -353,29 +359,30 @@ AutomationTimeAxisView::interpolation_changed ()
                        mode_discrete_item->set_active(false);
                }
        }
-
-       if (_line) {
-               _line->set_interpolation(style);
-       }
 }
 
+/** A menu item has been selected to change our interpolation mode */
 void
 AutomationTimeAxisView::set_interpolation (AutomationList::InterpolationStyle style)
 {
-       _control->list()->set_interpolation(style);
-       if (_line) {
-               _line->set_interpolation(style);
+       /* Tell our view's list, if we have one, otherwise tell our own.
+        * Everything else will be signalled back from that.
+        */
+       
+       if (_view) {
+               _view->set_interpolation (style);
+       } else {
+               _control->list()->set_interpolation (style);
        }
 }
 
 void
 AutomationTimeAxisView::clear_clicked ()
 {
-       _session->begin_reversible_command (_("clear automation"));
        if (_line) {
+               _session->begin_reversible_command (_("clear automation"));
                _line->clear ();
        }
-       _session->commit_reversible_command ();
 }
 
 void
@@ -532,6 +539,9 @@ AutomationTimeAxisView::build_display_menu ()
 
        /* mode menu */
 
+       /* current interpolation state */
+       AutomationList::InterpolationStyle const s = _view ? _view->interpolation() : _control->list()->interpolation ();
+
        if (EventTypeMap::instance().is_midi_parameter(_control->parameter())) {
 
                Menu* auto_mode_menu = manage (new Menu);
@@ -544,17 +554,13 @@ AutomationTimeAxisView::build_display_menu ()
                                sigc::mem_fun(*this, &AutomationTimeAxisView::set_interpolation),
                                AutomationList::Discrete)));
                mode_discrete_item = dynamic_cast<CheckMenuItem*>(&am_items.back());
-               mode_discrete_item->set_active(_control->list()->interpolation() == AutomationList::Discrete);
+               mode_discrete_item->set_active (s == AutomationList::Discrete);
 
                am_items.push_back (RadioMenuElem (group, _("Linear"), sigc::bind (
                                sigc::mem_fun(*this, &AutomationTimeAxisView::set_interpolation),
                                AutomationList::Linear)));
                mode_line_item = dynamic_cast<CheckMenuItem*>(&am_items.back());
-
-               // Set default interpolation type to linear if this isn't a (usually) discrete controller
-               if (EventTypeMap::instance().interpolation_of(_control->parameter()) == Evoral::ControlList::Linear) {
-                       mode_line_item->set_active(_control->list()->interpolation() == AutomationList::Linear);
-               }
+               mode_line_item->set_active (s == AutomationList::Linear);
 
                items.push_back (MenuElem (_("Mode"), *auto_mode_menu));
        }
@@ -562,7 +568,7 @@ AutomationTimeAxisView::build_display_menu ()
        /* make sure the automation menu state is correct */
 
        automation_state_changed ();
-       interpolation_changed ();
+       interpolation_changed (s);
 }
 
 void
@@ -820,7 +826,7 @@ void
 AutomationTimeAxisView::clear_lines ()
 {
        _line.reset();
-       automation_connection.disconnect ();
+       _list_connections.drop_connections ();
 }
 
 void
@@ -830,7 +836,13 @@ AutomationTimeAxisView::add_line (boost::shared_ptr<AutomationLine> line)
        assert(!_line);
        assert(line->the_list() == _control->list());
 
-       _control->alist()->automation_state_changed.connect (automation_connection, invalidator (*this), boost::bind (&AutomationTimeAxisView::automation_state_changed, this), gui_context());
+       _control->alist()->automation_state_changed.connect (
+               _list_connections, invalidator (*this), boost::bind (&AutomationTimeAxisView::automation_state_changed, this), gui_context()
+               );
+       
+       _control->alist()->InterpolationChanged.connect (
+               _list_connections, invalidator (*this), boost::bind (&AutomationTimeAxisView::interpolation_changed, this, _1), gui_context()
+               );
 
        _line = line;
        //_controller = AutomationController::create(_session, line->the_list(), _control);
@@ -934,3 +946,10 @@ AutomationTimeAxisView::set_visibility (bool yn)
 
        return changed;
 }
+
+/** @return true if this view has any automation data to display */
+bool
+AutomationTimeAxisView::has_automation () const
+{
+       return ( (_line && _line->npoints() > 0) || (_view && _view->has_automation()) );
+}