diff --git a/gtk2_ardour/audio_time_axis.cc b/gtk2_ardour/audio_time_axis.cc index 5fbb305299..3cd10f45d9 100644 --- a/gtk2_ardour/audio_time_axis.cc +++ b/gtk2_ardour/audio_time_axis.cc @@ -99,6 +99,11 @@ AudioTimeAxisView::set_route (boost::shared_ptr rt) create_automation_child (GainAutomation, false); } + /* if set_state above didn't create a mute automation child, we need to make one */ + if (automation_child (MuteAutomation) == 0) { + create_automation_child (MuteAutomation, false); + } + if (_route->panner_shell()) { _route->panner_shell()->Changed.connect (*this, invalidator (*this), boost::bind (&AudioTimeAxisView::ensure_pan_views, this, false), gui_context()); @@ -201,6 +206,11 @@ AudioTimeAxisView::create_automation_child (const Evoral::Parameter& param, bool /* handled elsewhere */ + } else if (param.type() == MuteAutomation) { + + create_mute_automation_child (param, show); + + } else { error << "AudioTimeAxisView: unknown automation child " << EventTypeMap::instance().to_symbol(param) << endmsg; } @@ -282,6 +292,22 @@ AudioTimeAxisView::update_gain_track_visibility () } } +void +AudioTimeAxisView::update_mute_track_visibility () +{ + bool const showit = mute_automation_item->get_active(); + + if (showit != string_is_affirmative (mute_track->gui_property ("visible"))) { + mute_track->set_marked_for_display (showit); + + /* now trigger a redisplay */ + + if (!no_redraw) { + _route->gui_changed (X_("visible_tracks"), (void *) 0); /* EMIT_SIGNAL */ + } + } +} + void AudioTimeAxisView::update_pan_track_visibility () { @@ -403,6 +429,13 @@ AudioTimeAxisView::build_automation_action_menu (bool for_selection) _main_automation_menu_map[Evoral::Parameter(GainAutomation)] = gain_automation_item; + automation_items.push_back (CheckMenuElem (_("Mute"), sigc::mem_fun (*this, &AudioTimeAxisView::update_mute_track_visibility))); + mute_automation_item = dynamic_cast (&automation_items.back ()); + mute_automation_item->set_active ((!for_selection || _editor.get_selection().tracks.size() == 1) && + (mute_track && string_is_affirmative (mute_track->gui_property ("visible")))); + + _main_automation_menu_map[Evoral::Parameter(MuteAutomation)] = mute_automation_item; + if (!pan_tracks.empty()) { automation_items.push_back (CheckMenuElem (_("Pan"), sigc::mem_fun (*this, &AudioTimeAxisView::update_pan_track_visibility))); pan_automation_item = dynamic_cast (&automation_items.back ()); diff --git a/gtk2_ardour/audio_time_axis.h b/gtk2_ardour/audio_time_axis.h index 5790080160..7a5afe4f97 100644 --- a/gtk2_ardour/audio_time_axis.h +++ b/gtk2_ardour/audio_time_axis.h @@ -105,9 +105,11 @@ class AudioTimeAxisView : public RouteTimeAxisView void update_control_names (); void update_gain_track_visibility (); + void update_mute_track_visibility (); void update_pan_track_visibility (); Gtk::CheckMenuItem* gain_automation_item; + Gtk::CheckMenuItem* mute_automation_item; std::list > pan_tracks; Gtk::CheckMenuItem* pan_automation_item; }; diff --git a/gtk2_ardour/midi_time_axis.cc b/gtk2_ardour/midi_time_axis.cc index 1b5080f92a..d1067e746e 100644 --- a/gtk2_ardour/midi_time_axis.cc +++ b/gtk2_ardour/midi_time_axis.cc @@ -179,6 +179,11 @@ MidiTimeAxisView::set_route (boost::shared_ptr rt) create_automation_child (GainAutomation, false); } + /* if set_state above didn't create a mute automation child, we need to make one */ + if (automation_child (MuteAutomation) == 0) { + create_automation_child (MuteAutomation, false); + } + if (_route->panner_shell()) { _route->panner_shell()->Changed.connect (*this, invalidator (*this), boost::bind (&MidiTimeAxisView::ensure_pan_views, this, false), gui_context()); } @@ -1281,6 +1286,10 @@ MidiTimeAxisView::create_automation_child (const Evoral::Parameter& param, bool create_gain_automation_child (param, show); break; + case MuteAutomation: + create_mute_automation_child (param, show); + break; + case PluginAutomation: /* handled elsewhere */ break; diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc index 964e78fa22..27c53fda7a 100644 --- a/gtk2_ardour/route_time_axis.cc +++ b/gtk2_ardour/route_time_axis.cc @@ -2402,6 +2402,30 @@ RouteTimeAxisView::create_gain_automation_child (const Evoral::Parameter& param, add_automation_child (Evoral::Parameter(GainAutomation), gain_track, show); } +void +RouteTimeAxisView::create_mute_automation_child (const Evoral::Parameter& param, bool show) +{ + boost::shared_ptr c = _route->mute_control(); + if (!c) { + error << "Route has no mute automation, unable to add automation track view." << endmsg; + return; + } + + mute_track.reset (new AutomationTimeAxisView (_session, + _route, _route, c, param, + _editor, + *this, + false, + parent_canvas, + _route->describe_parameter(param))); + + if (_view) { + _view->foreach_regionview (sigc::mem_fun (*mute_track.get(), &TimeAxisView::add_ghost)); + } + + add_automation_child (Evoral::Parameter(MuteAutomation), mute_track, show); +} + static void add_region_to_list (RegionView* rv, RegionList* l) { diff --git a/gtk2_ardour/route_time_axis.h b/gtk2_ardour/route_time_axis.h index 220b063577..5ee1f40ae1 100644 --- a/gtk2_ardour/route_time_axis.h +++ b/gtk2_ardour/route_time_axis.h @@ -240,11 +240,13 @@ protected: void color_handler (); void region_view_added (RegionView*); void create_gain_automation_child (const Evoral::Parameter &, bool); + void create_mute_automation_child (const Evoral::Parameter &, bool); void setup_processor_menu_and_curves (); void route_color_changed (); bool can_edit_name() const; boost::shared_ptr gain_track; + boost::shared_ptr mute_track; StreamView* _view; ArdourCanvas::Canvas& parent_canvas; diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h index 8119afae8a..badf1acc91 100644 --- a/libs/ardour/ardour/types.h +++ b/libs/ardour/ardour/types.h @@ -137,7 +137,7 @@ namespace ARDOUR { FadeInAutomation, FadeOutAutomation, EnvelopeAutomation, - RecEnableAutomation + RecEnableAutomation, }; enum AutoState { diff --git a/libs/ardour/automatable.cc b/libs/ardour/automatable.cc index 84f8cd56cc..7669f22df1 100644 --- a/libs/ardour/automatable.cc +++ b/libs/ardour/automatable.cc @@ -156,6 +156,8 @@ Automatable::describe_parameter (Evoral::Parameter param) if (param == Evoral::Parameter(GainAutomation)) { return _("Fader"); + } else if (param.type() == MuteAutomation) { + return _("Mute"); } else if (param.type() == MidiCCAutomation) { return string_compose("Controller %1 [%2]", param.id(), int(param.channel()) + 1); } else if (param.type() == MidiPgmChangeAutomation) { diff --git a/libs/ardour/event_type_map.cc b/libs/ardour/event_type_map.cc index 7cf6045d86..29a363c78b 100644 --- a/libs/ardour/event_type_map.cc +++ b/libs/ardour/event_type_map.cc @@ -163,14 +163,17 @@ EventTypeMap::new_parameter(uint32_t type, uint8_t channel, uint32_t id) const /* default 0.0 - 1.0 is fine */ break; case PluginAutomation: - case SoloAutomation: - case MuteAutomation: case FadeInAutomation: case FadeOutAutomation: case EnvelopeAutomation: max = 2.0f; normal = 1.0f; break; + case SoloAutomation: + case MuteAutomation: + max = 1.0f; + normal = 0.0f; + break; case MidiCCAutomation: case MidiPgmChangeAutomation: case MidiChannelPressureAutomation: diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index 81265e545f..fc79a21b15 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -3438,6 +3438,8 @@ Route::MuteControllable::set_value (double val) return; } + cerr << " _route->mute with val = " << val << endl; + rl->push_back (r); _session.set_mute (rl, bval); }