merge (with conflict fixes) with master (even against rgareus' recommendation)
[ardour.git] / gtk2_ardour / mixer_strip.cc
index 98b208f317f7d76f38f0e09cb83de78b7f581fb8..80548ea20b71c60a4b6d2fd525ed13fefadc269c 100644 (file)
@@ -41,6 +41,7 @@
 #include "ardour/pannable.h"
 #include "ardour/panner.h"
 #include "ardour/panner_shell.h"
+#include "ardour/panner_manager.h"
 #include "ardour/port.h"
 #include "ardour/profile.h"
 #include "ardour/route.h"
@@ -71,6 +72,7 @@ using namespace PBD;
 using namespace Gtk;
 using namespace Gtkmm2ext;
 using namespace std;
+using namespace ArdourMeter;
 
 int MixerStrip::scrollbar_height = 0;
 PBD::Signal1<void,MixerStrip*> MixerStrip::CatchDeletion;
@@ -514,7 +516,10 @@ MixerStrip::set_route (boost::shared_ptr<Route> rt)
        _route->output()->changed.connect (*this, invalidator (*this), boost::bind (&MixerStrip::update_output_display, this), gui_context());
        _route->route_group_changed.connect (route_connections, invalidator (*this), boost::bind (&MixerStrip::route_group_changed, this), gui_context());
 
+       _route->io_changed.connect (route_connections, invalidator (*this), boost::bind (&MixerStrip::io_changed_proxy, this), gui_context ());
+
        if (_route->panner_shell()) {
+               update_panner_choices();
                _route->panner_shell()->Changed.connect (route_connections, invalidator (*this), boost::bind (&MixerStrip::connect_to_pan, this), gui_context());
        }
 
@@ -697,7 +702,7 @@ MixerStrip::output_press (GdkEventButton *ev)
 {
        using namespace Menu_Helpers;
        if (!_session->engine().connected()) {
-               MessageDialog msg (_("Not connected to JACK - no I/O changes are possible"));
+               MessageDialog msg (_("Not connected to audio engine - no I/O changes are possible"));
                msg.run ();
                return true;
        }
@@ -825,7 +830,7 @@ MixerStrip::input_press (GdkEventButton *ev)
        citems.clear();
 
        if (!_session->engine().connected()) {
-               MessageDialog msg (_("Not connected to JACK - no I/O changes are possible"));
+               MessageDialog msg (_("Not connected to audio engine - no I/O changes are possible"));
                msg.run ();
                return true;
        }
@@ -1018,9 +1023,32 @@ MixerStrip::connect_to_pan ()
        p->automation_state_changed.connect (panstate_connection, invalidator (*this), boost::bind (&PannerUI::pan_automation_state_changed, &panners), gui_context());
        p->automation_style_changed.connect (panstyle_connection, invalidator (*this), boost::bind (&PannerUI::pan_automation_style_changed, &panners), gui_context());
 
-       panners.panshell_changed ();
+       /* This call reduncant, PannerUI::set_panner() connects to _panshell->Changed itself
+        * However, that only works a panner was previously set.
+        *
+        * PannerUI must remain subscribed to _panshell->Changed() in case
+        * we switch the panner eg. AUX-Send and back
+        * _route->panner_shell()->Changed() vs _panshell->Changed
+        */
+       if (panners._panner == 0) {
+               panners.panshell_changed ();
+       }
 }
 
+void
+MixerStrip::update_panner_choices ()
+{
+       ENSURE_GUI_THREAD (*this, &MixerStrip::update_panner_choices)
+       if (!_route->panner_shell()) { return; }
+
+       uint32_t in = _route->output()->n_ports().n_audio();
+       uint32_t out = in;
+       if (_route->panner()) {
+               in = _route->panner()->in().n_audio();
+       }
+
+       panners.set_available_panners(PannerManager::instance().PannerManager::get_available_panners(in, out));
+}
 
 /*
  * Output port labelling
@@ -1271,6 +1299,12 @@ MixerStrip::diskstream_changed ()
        Gtkmm2ext::UI::instance()->call_slot (invalidator (*this), boost::bind (&MixerStrip::update_diskstream_display, this));
 }
 
+void
+MixerStrip::io_changed_proxy ()
+{
+       Glib::signal_idle().connect_once (sigc::mem_fun (*this, &MixerStrip::update_panner_choices));
+}
+
 void
 MixerStrip::port_connected_or_disconnected (boost::weak_ptr<Port> wa, boost::weak_ptr<Port> wb)
 {
@@ -1472,7 +1506,7 @@ MixerStrip::build_route_ops_menu ()
 
        items.push_back (SeparatorElem());
        items.push_back (CheckMenuElem (_("Active")));
-       CheckMenuItem* i = dynamic_cast<CheckMenuItem *> (&items.back());
+       Gtk::CheckMenuItem* i = dynamic_cast<Gtk::CheckMenuItem *> (&items.back());
        i->set_active (_route->active());
        i->signal_activate().connect (sigc::bind (sigc::mem_fun (*this, &RouteUI::set_route_active), !_route->active(), false));
 
@@ -1482,7 +1516,7 @@ MixerStrip::build_route_ops_menu ()
 
        items.push_back (SeparatorElem());
        items.push_back (CheckMenuElem (_("Protect Against Denormals"), sigc::mem_fun (*this, &RouteUI::toggle_denormal_protection)));
-       denormal_menu_item = dynamic_cast<CheckMenuItem *> (&items.back());
+       denormal_menu_item = dynamic_cast<Gtk::CheckMenuItem *> (&items.back());
        denormal_menu_item->set_active (_route->denormal_protection());
 
        if (!Profile->get_sae()) {
@@ -1841,16 +1875,13 @@ MixerStrip::show_send (boost::shared_ptr<Send> send)
        gain_meter().set_controls (_route, send->meter(), send->amp());
        gain_meter().setup_meters ();
 
+       uint32_t const in = _current_delivery->pans_required();
+       uint32_t const out = _current_delivery->pan_outs();
+
        panner_ui().set_panner (_current_delivery->panner_shell(), _current_delivery->panner());
+       panner_ui().set_available_panners(PannerManager::instance().PannerManager::get_available_panners(in, out));
        panner_ui().setup_pan ();
-
-       /* make sure the send has audio output */
-
-       if (_current_delivery->output() && _current_delivery->output()->n_ports().n_audio() > 0) {
-               panners.show_all ();
-       } else {
-               panners.hide_all ();
-       }
+       panner_ui().show_all ();
 
        input_button.set_sensitive (false);
        group_button.set_sensitive (false);
@@ -1883,6 +1914,7 @@ MixerStrip::revert_to_default_display ()
        gain_meter().setup_meters ();
 
        panner_ui().set_panner (_route->main_outs()->panner_shell(), _route->main_outs()->panner());
+       update_panner_choices();
        panner_ui().setup_pan ();
 
        if (has_audio_outputs ()) {
@@ -2104,6 +2136,9 @@ MixerStrip::ab_plugins ()
 bool
 MixerStrip::level_meter_button_press (GdkEventButton* ev)
 {
+       if (_current_delivery && boost::dynamic_pointer_cast<Send>(_current_delivery)) {
+               return false;
+       }
        if (ev->button == 3) {
                popup_level_meter_menu (ev);
                return true;
@@ -2132,8 +2167,16 @@ MixerStrip::popup_level_meter_menu (GdkEventButton* ev)
        RadioMenuItem::Group tgroup;
        items.push_back (SeparatorElem());
 
-       add_level_meter_item_type (items, tgroup, _("Peak"), MeterPeak);
-       add_level_meter_item_type (items, tgroup, _("RMS + Peak"), MeterKrms);
+       add_level_meter_item_type (items, tgroup, ArdourMeter::meter_type_string(MeterPeak), MeterPeak);
+       add_level_meter_item_type (items, tgroup, ArdourMeter::meter_type_string(MeterKrms),  MeterKrms);
+       add_level_meter_item_type (items, tgroup, ArdourMeter::meter_type_string(MeterIEC1DIN), MeterIEC1DIN);
+       add_level_meter_item_type (items, tgroup, ArdourMeter::meter_type_string(MeterIEC1NOR), MeterIEC1NOR);
+       add_level_meter_item_type (items, tgroup, ArdourMeter::meter_type_string(MeterIEC2BBC), MeterIEC2BBC);
+       add_level_meter_item_type (items, tgroup, ArdourMeter::meter_type_string(MeterIEC2EBU), MeterIEC2EBU);
+       add_level_meter_item_type (items, tgroup, ArdourMeter::meter_type_string(MeterK20), MeterK20);
+       add_level_meter_item_type (items, tgroup, ArdourMeter::meter_type_string(MeterK14), MeterK14);
+       add_level_meter_item_type (items, tgroup, ArdourMeter::meter_type_string(MeterK12), MeterK12);
+       add_level_meter_item_type (items, tgroup, ArdourMeter::meter_type_string(MeterVU),  MeterVU);
 
        int _strip_type;
        if (_route->is_master()) {
@@ -2151,13 +2194,16 @@ MixerStrip::popup_level_meter_menu (GdkEventButton* ev)
                _strip_type = 1;
        }
 
+       MeterType cmt = _route->meter_type();
+       const std::string cmn = ArdourMeter::meter_type_string(cmt);
+
        items.push_back (SeparatorElem());
-       items.push_back (MenuElem (_("Change all in Group to Peak"), sigc::bind (SetMeterTypeMulti, -1, _route->route_group(), MeterPeak)));
-       items.push_back (MenuElem (_("Change all in Group to RMS + Peak"), sigc::bind (SetMeterTypeMulti, -1, _route->route_group(), MeterKrms)));
-       items.push_back (MenuElem (_("Change all to Peak"), sigc::bind (SetMeterTypeMulti, 0, _route->route_group(), MeterPeak)));
-       items.push_back (MenuElem (_("Change all to RMS + Peak"), sigc::bind (SetMeterTypeMulti, 0, _route->route_group(), MeterKrms)));
-       items.push_back (MenuElem (_("Change same track-type to Peak"), sigc::bind (SetMeterTypeMulti, _strip_type, _route->route_group(), MeterPeak)));
-       items.push_back (MenuElem (_("Change same track-type to RMS + Peak"), sigc::bind (SetMeterTypeMulti, _strip_type, _route->route_group(), MeterKrms)));
+       items.push_back (MenuElem (string_compose(_("Change all in Group to %1"), cmn),
+                               sigc::bind (SetMeterTypeMulti, -1, _route->route_group(), cmt)));
+       items.push_back (MenuElem (string_compose(_("Change all to %1"), cmn),
+                               sigc::bind (SetMeterTypeMulti, 0, _route->route_group(), cmt)));
+       items.push_back (MenuElem (string_compose(_("Change same track-type to %1"), cmn),
+                               sigc::bind (SetMeterTypeMulti, _strip_type, _route->route_group(), cmt)));
 
        m->popup (ev->button, ev->time);
        _suspend_menu_callbacks = false;