X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Froute_ui.cc;h=1ce6114a3e7621ac5051286d1333a4cc25fc844d;hb=3c25d26e91d4703ba76c90d5175aa94e4ddd850b;hp=4427810bdeefaeca8b8e0bff4c90bd82d45abbab;hpb=d233b33707b0600e777800534a8c0a47e8a86511;p=ardour.git diff --git a/gtk2_ardour/route_ui.cc b/gtk2_ardour/route_ui.cc index 4427810bde..1ce6114a3e 100644 --- a/gtk2_ardour/route_ui.cc +++ b/gtk2_ardour/route_ui.cc @@ -17,6 +17,7 @@ */ +#include #include #include @@ -38,11 +39,13 @@ #include "ardour/vca.h" #include "ardour/vca_manager.h" #include "ardour/audio_track.h" +#include "ardour/audio_port.h" #include "ardour/audioengine.h" #include "ardour/filename_extensions.h" #include "ardour/midi_track.h" #include "ardour/monitor_control.h" #include "ardour/internal_send.h" +#include "ardour/panner_shell.h" #include "ardour/profile.h" #include "ardour/phase_control.h" #include "ardour/send.h" @@ -71,7 +74,7 @@ #include "utils.h" -#include "i18n.h" +#include "pbd/i18n.h" using namespace Gtk; using namespace Gtkmm2ext; using namespace ARDOUR; @@ -85,7 +88,9 @@ boost::weak_ptr RouteUI::_showing_sends_to; std::string RouteUI::program_port_prefix; RouteUI::RouteUI (ARDOUR::Session* sess) - : mute_menu(0) + : monitor_input_button (0) + , monitor_disk_button (0) + , mute_menu(0) , solo_menu(0) , sends_menu(0) , record_menu(0) @@ -123,6 +128,8 @@ RouteUI::~RouteUI() delete comment_window; delete input_selector; delete output_selector; + delete monitor_input_button; + delete monitor_disk_button; delete _invert_menu; send_blink_connection.disconnect (); @@ -182,13 +189,13 @@ RouteUI::init () show_sends_button->set_name ("send alert button"); UI::instance()->set_tip (show_sends_button, _("make mixer strips show sends to this bus"), ""); - monitor_input_button = manage (new ArdourButton (ArdourButton::default_elements)); + monitor_input_button = new ArdourButton (ArdourButton::default_elements); monitor_input_button->set_name ("monitor button"); monitor_input_button->set_text (_("In")); UI::instance()->set_tip (monitor_input_button, _("Monitor input"), ""); monitor_input_button->set_no_show_all (true); - monitor_disk_button = manage (new ArdourButton (ArdourButton::default_elements)); + monitor_disk_button = new ArdourButton (ArdourButton::default_elements); monitor_disk_button->set_name ("monitor button"); monitor_disk_button->set_text (_("Disk")); UI::instance()->set_tip (monitor_disk_button, _("Monitor playback"), ""); @@ -200,6 +207,7 @@ RouteUI::init () _session->config.ParameterChanged.connect (*this, invalidator (*this), boost::bind (&RouteUI::parameter_changed, this, _1), gui_context()); Config->ParameterChanged.connect (*this, invalidator (*this), boost::bind (&RouteUI::parameter_changed, this, _1), gui_context()); + UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (this, &RouteUI::parameter_changed)); rec_enable_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::rec_enable_press), false); rec_enable_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::rec_enable_release), false); @@ -277,10 +285,13 @@ RouteUI::set_route (boost::shared_ptr rp) _route->solo_safe_control()->Changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::update_solo_display, this), gui_context()); _route->solo_isolate_control()->Changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::update_solo_display, this), gui_context()); _route->phase_control()->Changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::polarity_changed, this), gui_context()); + _route->fan_out.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::fan_out, this, true, true), gui_context()); if (is_track()) { track()->FreezeChange.connect (*this, invalidator (*this), boost::bind (&RouteUI::map_frozen, this), gui_context()); +#ifdef XXX_OLD_DESTRUCTIVE_API_XXX track()->TrackModeChanged.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::track_mode_changed, this), gui_context()); +#endif track_mode_changed(); } @@ -418,7 +429,6 @@ RouteUI::mute_press (GdkEventButton* ev) _mute_release->routes = copy; } - DisplaySuspender ds; _session->set_controls (route_list_to_control_list (copy, &Stripable::mute_control), _route->muted_by_self() ? 0.0 : 1.0, Controllable::UseGroup); } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) { @@ -447,7 +457,6 @@ RouteUI::mute_press (GdkEventButton* ev) _mute_release->routes = rl; } - DisplaySuspender ds; _session->set_controls (route_list_to_control_list (rl, &Stripable::mute_control), _route->muted_by_self() ? 0.0 : 1.0, Controllable::InverseGroup); } @@ -474,7 +483,6 @@ bool RouteUI::mute_release (GdkEventButton* /*ev*/) { if (_mute_release){ - DisplaySuspender ds; _session->set_controls (route_list_to_control_list (_mute_release->routes, &Stripable::mute_control), _mute_release->active, Controllable::UseGroup); delete _mute_release; _mute_release = 0; @@ -574,7 +582,6 @@ RouteUI::solo_press(GdkEventButton* ev) _solo_release->routes = _session->get_routes (); } - DisplaySuspender ds; _session->set_controls (route_list_to_control_list (_session->get_routes(), &Stripable::solo_control), !_route->solo_control()->get_value(), Controllable::UseGroup); } else if (Keyboard::modifier_state_contains (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::SecondaryModifier))) { @@ -644,8 +651,6 @@ RouteUI::solo_press(GdkEventButton* ev) _solo_release->routes = rl; } - DisplaySuspender ds; - _session->set_controls (route_list_to_control_list (rl, &Stripable::solo_control), !_route->self_soloed(), Controllable::InverseGroup); } @@ -663,7 +668,6 @@ RouteUI::solo_press(GdkEventButton* ev) _solo_release->routes = rl; } - DisplaySuspender ds; _session->set_controls (route_list_to_control_list (rl, &Stripable::solo_control), !_route->self_soloed(), Controllable::UseGroup); } } @@ -680,7 +684,6 @@ RouteUI::solo_release (GdkEventButton* /*ev*/) if (_solo_release->exclusive) { } else { - DisplaySuspender ds; _session->set_controls (route_list_to_control_list (_solo_release->routes, &Stripable::solo_control), _solo_release->active ? 1.0 : 0.0, Controllable::UseGroup); } @@ -727,7 +730,6 @@ RouteUI::rec_enable_press(GdkEventButton* ev) } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::TertiaryModifier))) { - DisplaySuspender ds; _session->set_controls (route_list_to_control_list (_session->get_routes(), &Stripable::rec_enable_control), !track()->rec_enable_control()->get_value(), Controllable::NoGroup); } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) { @@ -743,7 +745,6 @@ RouteUI::rec_enable_press(GdkEventButton* ev) rl.reset (new RouteList); rl->push_back (_route); - DisplaySuspender ds; _session->set_controls (route_list_to_control_list (rl, &Stripable::rec_enable_control), !track()->rec_enable_control()->get_value(), Controllable::InverseGroup); } @@ -865,7 +866,6 @@ RouteUI::monitor_release (GdkEventButton* ev, MonitorChoice monitor_choice) rl->push_back (route()); } - DisplaySuspender ds; _session->set_controls (route_list_to_control_list (rl, &Stripable::monitoring_control), (double) mc, Controllable::UseGroup); return false; @@ -1200,28 +1200,28 @@ RouteUI::update_solo_display () solo_isolated_check->set_active (yn); } - set_button_names (); + set_button_names (); - if (solo_isolated_led) { - if (_route->solo_isolate_control()->solo_isolated()) { + if (solo_isolated_led) { + if (_route->solo_isolate_control()->solo_isolated()) { solo_isolated_led->set_active_state (Gtkmm2ext::ExplicitActive); } else { solo_isolated_led->unset_active_state (); } - } + } - if (solo_safe_led) { - if (_route->solo_safe_control()->solo_safe()) { + if (solo_safe_led) { + if (_route->solo_safe_control()->solo_safe()) { solo_safe_led->set_active_state (Gtkmm2ext::ExplicitActive); } else { solo_safe_led->unset_active_state (); } - } + } solo_button->set_active_state (solo_active_state (_route)); - /* some changes to solo status can affect mute display, so catch up - */ + /* some changes to solo status can affect mute display, so catch up + */ update_mute_display (); } @@ -1289,15 +1289,13 @@ RouteUI::update_mute_display () void RouteUI::route_rec_enable_changed () { - blink_rec_display(true); //this lets the button change "immediately" rather than wait for the next blink - update_monitoring_display (); + blink_rec_display (true); //this lets the button change "immediately" rather than wait for the next blink } void RouteUI::session_rec_enable_changed () { - blink_rec_display(true); //this lets the button change "immediately" rather than wait for the next blink - update_monitoring_display (); + blink_rec_display (true); //this lets the button change "immediately" rather than wait for the next blink } void @@ -1481,11 +1479,9 @@ RouteUI::solo_isolate_button_release (GdkEventButton* ev) if (model) { /* disable isolate for all routes */ - DisplaySuspender ds; _session->set_controls (route_list_to_control_list (_session->get_routes(), &Stripable::solo_isolate_control), 0.0, Controllable::NoGroup); } else { /* enable isolate for all routes */ - DisplaySuspender ds; _session->set_controls (route_list_to_control_list (_session->get_routes(), &Stripable::solo_isolate_control), 1.0, Controllable::NoGroup); } @@ -1497,7 +1493,6 @@ RouteUI::solo_isolate_button_release (GdkEventButton* ev) boost::shared_ptr rl (new RouteList); rl->push_back (_route); - DisplaySuspender ds; _session->set_controls (route_list_to_control_list (rl, &Stripable::solo_isolate_control), view ? 0.0 : 1.0, Controllable::NoGroup); } } @@ -1569,7 +1564,7 @@ void RouteUI::choose_color () { bool picked; - Gdk::Color c (gdk_color_from_rgb (_route->presentation_info().color())); + Gdk::Color c (gdk_color_from_rgba (_route->presentation_info().color())); Gdk::Color const color = Gtkmm2ext::UI::instance()->get_color (_("Color Selection"), picked, &c); if (picked) { @@ -1946,6 +1941,8 @@ RouteUI::parameter_changed (string const & p) check_rec_enable_sensitivity (); } else if (p == "use-monitor-bus" || p == "solo-control-is-listen-control" || p == "listen-position") { set_button_names (); + } else if (p == "session-monitoring") { + update_monitoring_display (); } else if (p == "auto-input") { update_monitoring_display (); } else if (p == "blink-rec-arm") { @@ -2146,33 +2143,6 @@ RouteUI::route_gui_changed (PropertyChange const& what_changed) route_color_changed (); } } - - if (what_changed.contains (Properties::selected)) { - show_selected (); - } -} - -void -RouteUI::set_selected (bool yn) -{ - Selectable::set_selected (yn); - if (_route) { - _route->presentation_info().set_selected (yn); - } -} - -bool -RouteUI::selected () const -{ - /* XXX not sure if this is a wise design. Probably don't really want - * the cached _selected value from Selectable. - */ - - if (!_route) { - return _selected; - } - - return _route->presentation_info().selected(); } void @@ -2320,6 +2290,7 @@ RoutePinWindowProxy::route_going_away () _window = 0; WM::Manager::instance().remove (this); going_away_connection.disconnect(); + delete this; } void @@ -2358,6 +2329,97 @@ RouteUI::manage_pins () } } +void +RouteUI::fan_out (bool to_busses, bool group) +{ + DisplaySuspender ds; + boost::shared_ptr route = _route; + boost::shared_ptr pi = boost::dynamic_pointer_cast (route->the_instrument ()); + assert (pi); + + const uint32_t n_outputs = pi->output_streams ().n_audio (); + if (route->n_outputs ().n_audio () != n_outputs) { + MessageDialog msg (string_compose ( + _("The Plugin's number of audio outputs ports (%1) does not match the Tracks's number of audio outputs (%2). Cannot fan out."), + n_outputs, route->n_outputs ().n_audio ())); + msg.run (); + return; + } + +#define BUSNAME pd.group_name + "(" + route->name () + ")" + + /* count busses and channels/bus */ + boost::shared_ptr plugin = pi->plugin (); + std::map busnames; + for (uint32_t p = 0; p < n_outputs; ++p) { + const Plugin::IOPortDescription& pd (plugin->describe_io_port (DataType::AUDIO, false, p)); + std::string bn = BUSNAME; + busnames[bn]++; + } + + if (busnames.size () < 2) { + MessageDialog msg (_("Instrument has only 1 output bus. Nothing to fan out.")); + msg.run (); + return; + } + + uint32_t outputs = 2; + if (_session->master_out ()) { + outputs = std::max (outputs, _session->master_out ()->n_inputs ().n_audio ()); + } + + route->output ()->disconnect (this); + route->panner_shell ()->set_bypassed (true); + + RouteList to_group; + for (uint32_t p = 0; p < n_outputs; ++p) { + const Plugin::IOPortDescription& pd (plugin->describe_io_port (DataType::AUDIO, false, p)); + std::string bn = BUSNAME; + boost::shared_ptr r = _session->route_by_name (bn); + if (!r) { + if (to_busses) { + RouteList rl = _session->new_audio_route (busnames[bn], outputs, NULL, 1, bn, PresentationInfo::AudioBus, PresentationInfo::max_order); + r = rl.front (); + assert (r); + } else { + list > tl = + _session->new_audio_track (busnames[bn], outputs, NULL, 1, bn, PresentationInfo::max_order, Normal); + r = tl.front (); + assert (r); + + boost::shared_ptr cl (new ControlList); + cl->push_back (r->monitoring_control ()); + _session->set_controls (cl, (double) MonitorInput, Controllable::NoGroup); + } + r->input ()->disconnect (this); + } + to_group.push_back (r); + route->output ()->audio (p)->connect (r->input ()->audio (pd.group_channel).get()); + } +#undef BUSNAME + + if (group) { + RouteGroup* rg = NULL; + const std::list& rgs (_session->route_groups ()); + for (std::list::const_iterator i = rgs.begin (); i != rgs.end (); ++i) { + if ((*i)->name () == pi->name ()) { + rg = *i; + break; + } + } + if (!rg) { + rg = new RouteGroup (*_session, pi->name ()); + _session->add_route_group (rg); + rg->set_gain (false); + } + + GroupTabs::set_group_color (rg, route->presentation_info().color()); + for (RouteList::const_iterator i = to_group.begin(); i != to_group.end(); ++i) { + rg->add (*i); + } + } +} + bool RouteUI::mark_hidden (bool yn) { @@ -2367,3 +2429,10 @@ RouteUI::mark_hidden (bool yn) } return false; } + +boost::shared_ptr +RouteUI::stripable () const +{ + return _route; +} +