From 9b5a071c3317697bec9fd4269d86b2f254816f38 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Fri, 9 Oct 2015 14:01:22 -0400 Subject: varied and wide changes to get input and output combos closer to working --- libs/surfaces/mackie/gui.cc | 142 +++++++++++++++++++----- libs/surfaces/mackie/gui.h | 18 ++- libs/surfaces/mackie/mackie_control_protocol.cc | 35 +++++- libs/surfaces/mackie/mackie_control_protocol.h | 9 +- libs/surfaces/mackie/surface.cc | 15 +-- libs/surfaces/mackie/surface.h | 6 +- 6 files changed, 181 insertions(+), 44 deletions(-) diff --git a/libs/surfaces/mackie/gui.cc b/libs/surfaces/mackie/gui.cc index 61fc718157..e627d797e5 100644 --- a/libs/surfaces/mackie/gui.cc +++ b/libs/surfaces/mackie/gui.cc @@ -239,6 +239,67 @@ MackieControlProtocolGUI::MackieControlProtocolGUI (MackieControlProtocol& p) fkey_packer->show_all(); } +void +MackieControlProtocolGUI::update_port_combos (vector const& midi_inputs, vector const& midi_outputs, + Gtk::ComboBoxText* input_combo, + Gtk::ComboBoxText* output_combo, + boost::shared_ptr surface) +{ + vector short_midi_inputs; + vector short_midi_outputs; + + /* Prepend "Disconnected" */ + + short_midi_inputs.push_back (_("Disconnected")); + short_midi_outputs.push_back (_("Disconnected")); + + /* generate short versions of all the port names */ + + for (vector::const_iterator s = midi_inputs.begin(); s != midi_inputs.end(); ++s) { + short_midi_inputs.push_back ((*s).substr ((*s).find (':') + 1)); + } + for (vector::const_iterator s = midi_outputs.begin(); s != midi_outputs.end(); ++s) { + short_midi_outputs.push_back ((*s).substr ((*s).find (':') + 1)); + } + + bool input_found = false; + bool output_found = true; + + Gtkmm2ext::set_popdown_strings (*input_combo, short_midi_inputs); + + vector::iterator shrt = short_midi_inputs.begin(); + shrt++; /* skip "Disconnected" */ + + for (vector::const_iterator s = midi_inputs.begin(); s != midi_inputs.end(); ++s, ++shrt) { + if (surface->port().input().connected_to (*s)) { + input_combo->set_active_text (*shrt); + input_found = true; + break; + } + } + + if (!input_found) { + input_combo->set_active_text (_("Disconnected")); + } + + Gtkmm2ext::set_popdown_strings (*output_combo, short_midi_outputs); + + shrt = short_midi_outputs.begin(); + shrt++; /* skip "Disconnected" */ + + for (vector::const_iterator s = midi_outputs.begin(); s != midi_outputs.end(); ++s, ++shrt) { + if (surface->port().output().connected_to (*s)) { + output_combo->set_active_text (*shrt); + output_found = true; + break; + } + } + + if (!output_found) { + output_combo->set_active_text (_("Disconnected")); + } +} + Gtk::Widget* MackieControlProtocolGUI::device_dependent_widget () { @@ -267,21 +328,12 @@ MackieControlProtocolGUI::device_dependent_widget () ARDOUR::AudioEngine::instance()->get_ports ("", ARDOUR::DataType::MIDI, ARDOUR::PortFlags (ARDOUR::IsOutput|ARDOUR::IsPhysical), midi_inputs); ARDOUR::AudioEngine::instance()->get_ports ("", ARDOUR::DataType::MIDI, ARDOUR::PortFlags (ARDOUR::IsInput|ARDOUR::IsPhysical), midi_outputs); - - port_combos.clear (); + input_combos.clear (); + output_combos.clear (); if (!_cp.device_info().uses_ipmidi()) { - for (uint32_t n = 0; n < n_surfaces; ++n) { - - - Gtk::ComboBoxText* input_combo = manage (new Gtk::ComboBoxText); - Gtk::ComboBoxText* output_combo = manage (new Gtk::ComboBoxText); - port_combos.push_back (input_combo); - port_combos.push_back (output_combo); - - Gtkmm2ext::set_popdown_strings (*output_combo, midi_outputs); - Gtkmm2ext::set_popdown_strings (*input_combo, midi_inputs); + for (uint32_t n = 0; n < n_surfaces; ++n) { boost::shared_ptr surface = _cp.nth_surface (n); @@ -290,20 +342,16 @@ MackieControlProtocolGUI::device_dependent_widget () /*NOTREACHED*/ } - for (vector::iterator s = midi_inputs.begin(); s != midi_inputs.end(); ++s) { + Gtk::ComboBoxText* input_combo = manage (new Gtk::ComboBoxText); + Gtk::ComboBoxText* output_combo = manage (new Gtk::ComboBoxText); - if (surface->port().input().connected_to (*s)) { - input_combo->set_active_text (*s); - break; - } - } + input_combo->set_data ("surface", surface.get()); + output_combo->set_data ("surface", surface.get()); - for (vector::iterator s = midi_outputs.begin(); s != midi_outputs.end(); ++s) { - if (surface->port().output().connected_to (*s)) { - output_combo->set_active_text (*s); - break; - } - } + input_combos.push_back (input_combo); + output_combos.push_back (output_combo); + + update_port_combos (midi_inputs, midi_outputs, input_combo, output_combo, surface); string send_string; string receive_string; @@ -721,7 +769,7 @@ void MackieControlProtocolGUI::surface_combo_changed () { _cp.not_session_load(); - _cp.set_device (_surface_combo.get_active_text()); + _cp.set_device (_surface_combo.get_active_text(), false); } void @@ -779,3 +827,47 @@ MackieControlProtocolGUI::touch_sensitive_change () int sensitivity = (int) touch_sensitivity_adjustment.get_value (); _cp.set_touch_sensitivity (sensitivity); } + +void +MackieControlProtocolGUI::surface_connectivity_change (Surface* raw_surface) +{ + boost::shared_ptr surface; + + for (MackieControlProtocol::Surfaces::iterator s = _cp.surfaces.begin(); s != _cp.surfaces.end(); ++s) { + if ((*s).get() == raw_surface) { + surface = *s; + break; + } + } + + if (!surface) { + return; + } + + Gtk::ComboBoxText* input_combo = 0; + Gtk::ComboBoxText* output_combo = 0; + + for (vector::iterator c = input_combos.begin(); c != input_combos.end(); ++c) { + if ((*c)->get_data ("surface") == raw_surface) { + input_combo = *c; + } + } + + for (vector::iterator c = output_combos.begin(); c != output_combos.end(); ++c) { + if ((*c)->get_data ("surface") == raw_surface) { + output_combo = *c; + } + } + + if (!input_combo || !output_combo) { + return; + } + + vector midi_inputs; + vector midi_outputs; + + ARDOUR::AudioEngine::instance()->get_ports ("", ARDOUR::DataType::MIDI, ARDOUR::PortFlags (ARDOUR::IsOutput|ARDOUR::IsPhysical), midi_inputs); + ARDOUR::AudioEngine::instance()->get_ports ("", ARDOUR::DataType::MIDI, ARDOUR::PortFlags (ARDOUR::IsInput|ARDOUR::IsPhysical), midi_outputs); + + update_port_combos (midi_inputs, midi_outputs, input_combo, output_combo, surface); +} diff --git a/libs/surfaces/mackie/gui.h b/libs/surfaces/mackie/gui.h index 934736a33d..8421068fd8 100644 --- a/libs/surfaces/mackie/gui.h +++ b/libs/surfaces/mackie/gui.h @@ -39,6 +39,10 @@ namespace ArdourSurface { class MackieControlProtocol; +namespace Mackie { + class Surface; +} + class MackieControlProtocolGUI : public Gtk::Notebook { public: @@ -51,7 +55,8 @@ class MackieControlProtocolGUI : public Gtk::Notebook Gtk::ComboBoxText _profile_combo; typedef std::vector PortCombos; - PortCombos port_combos; + PortCombos input_combos; + PortCombos output_combos; struct AvailableActionColumns : public Gtk::TreeModel::ColumnRecord { AvailableActionColumns() { @@ -124,6 +129,17 @@ class MackieControlProtocolGUI : public Gtk::Notebook PBD::ScopedConnection device_change_connection; void device_changed (); + + void update_port_combos (std::vector const&, std::vector const&, + Gtk::ComboBoxText* input_combo, + Gtk::ComboBoxText* output_combo, + boost::shared_ptr surface); + + /* this takes a raw pointer to Surface, because it connects to a signal + emitted by a Surface and we don't want to use + boost::shared_from_this. + */ + void surface_connectivity_change (Mackie::Surface* raw_surface); }; } diff --git a/libs/surfaces/mackie/mackie_control_protocol.cc b/libs/surfaces/mackie/mackie_control_protocol.cc index 6027c8b504..6f942445f8 100644 --- a/libs/surfaces/mackie/mackie_control_protocol.cc +++ b/libs/surfaces/mackie/mackie_control_protocol.cc @@ -686,19 +686,20 @@ MackieControlProtocol::set_device_info (const string& device_name) } int -MackieControlProtocol::set_device (const string& device_name) +MackieControlProtocol::set_device (const string& device_name, bool force) { - if (device_name == device_info().name()) { + if (device_name == device_info().name() && !force) { /* already using that device, nothing to do */ return 0; } if (set_device_info (device_name)) { + cerr << "Unknown device name\n"; return -1; } clear_surfaces (); - + port_connection.disconnect (); hui_connection.disconnect (); if (_device_info.device_type() == DeviceInfo::HUI) { @@ -711,6 +712,10 @@ MackieControlProtocol::set_device (const string& device_name) return -1; } + if (!_device_info.uses_ipmidi()) { + ARDOUR::AudioEngine::instance()->PortConnectedOrDisconnected.connect (port_connection, MISSING_INVALIDATOR, boost::bind (&MackieControlProtocol::connection_handler, this, _1, _2, _3, _4, _5), this); + } + switch_banks (0, true); DeviceChanged (); @@ -1766,10 +1771,14 @@ MackieControlProtocol::ipmidi_restart () void MackieControlProtocol::clear_surfaces () { + port_connection.disconnect (); clear_ports (); - Glib::Threads::Mutex::Lock lm (surfaces_lock); - _master_surface.reset (); - surfaces.clear (); + + { + Glib::Threads::Mutex::Lock lm (surfaces_lock); + _master_surface.reset (); + surfaces.clear (); + } } void @@ -1818,3 +1827,17 @@ MackieControlProtocol::nth_surface (uint32_t n) const return boost::shared_ptr (); } + +void +MackieControlProtocol::connection_handler (boost::weak_ptr wp1, std::string name1, boost::weak_ptr wp2, std::string name2, bool yn) +{ + Glib::Threads::Mutex::Lock lm (surfaces_lock); + + for (Surfaces::const_iterator s = surfaces.begin(); s != surfaces.end(); ++s) { + if ((*s)->connection_handler (wp1, name1, wp2, name2, yn)) { + cerr << (*s)->name() << " Connected, or disconnected\n"; + ConnectionChange (*s); + break; + } + } +} diff --git a/libs/surfaces/mackie/mackie_control_protocol.h b/libs/surfaces/mackie/mackie_control_protocol.h index 9b85c278b3..14beb707f4 100644 --- a/libs/surfaces/mackie/mackie_control_protocol.h +++ b/libs/surfaces/mackie/mackie_control_protocol.h @@ -44,6 +44,7 @@ namespace ARDOUR { class AutomationControl; + class Port; } namespace MIDI { @@ -133,11 +134,12 @@ class MackieControlProtocol Mackie::DeviceProfile& device_profile() { return _device_profile; } PBD::Signal0 DeviceChanged; + PBD::Signal1 > ConnectionChange; void device_ready (); int set_active (bool yn); - int set_device (const std::string&); + int set_device (const std::string&, bool force); void set_profile (const std::string&); FlipMode flip_mode () const { return _flip_mode; } @@ -350,6 +352,11 @@ class MackieControlProtocol void initialize (); int set_device_info (const std::string& device_name); + /* MIDI port connection management */ + + PBD::ScopedConnection port_connection; + void connection_handler (boost::weak_ptr, std::string name1, boost::weak_ptr, std::string name2, bool); + /* BUTTON HANDLING */ typedef std::set DownButtonList; diff --git a/libs/surfaces/mackie/surface.cc b/libs/surfaces/mackie/surface.cc index 7beaef59fa..7709ebb264 100644 --- a/libs/surfaces/mackie/surface.cc +++ b/libs/surfaces/mackie/surface.cc @@ -125,9 +125,7 @@ Surface::Surface (MackieControlProtocol& mcp, const std::string& device_name, ui DEBUG_TRACE (DEBUG::MackieControl, "init_strips done\n"); } - if (!_mcp.device_info().uses_ipmidi()) { - ARDOUR::AudioEngine::instance()->PortConnectedOrDisconnected.connect (port_connection, MISSING_INVALIDATOR, boost::bind (&Surface::connection_handler, this, _1, _2, _3, _4, _5), &_mcp); - } else { + if (_mcp.device_info().uses_ipmidi()) { /* ipMIDI port already exists, we can just assume that we're * connected. * @@ -149,8 +147,6 @@ Surface::~Surface () { DEBUG_TRACE (DEBUG::MackieControl, "Surface::~Surface init\n"); - port_connection.disconnect (); - if (input_source) { g_source_destroy (input_source); input_source = 0; @@ -172,11 +168,11 @@ Surface::~Surface () DEBUG_TRACE (DEBUG::MackieControl, "Surface::~Surface done\n"); } -void +bool Surface::connection_handler (boost::weak_ptr, std::string name1, boost::weak_ptr, std::string name2, bool yn) { if (!_port) { - return; + return false; } string ni = ARDOUR::AudioEngine::instance()->make_port_name_non_relative (_port->input_name()); @@ -194,6 +190,9 @@ Surface::connection_handler (boost::weak_ptr, std::string name1, b } else { connection_state &= ~OutputConnected; } + } else { + /* not our ports */ + return false; } if ((connection_state & (InputConnected|OutputConnected)) == (InputConnected|OutputConnected)) { @@ -228,6 +227,8 @@ Surface::connection_handler (boost::weak_ptr, std::string name1, b DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Surface %1 disconnected (input or output or both)\n", _name)); _active = false; } + + return true; /* connection status changed */ } XMLNode& diff --git a/libs/surfaces/mackie/surface.h b/libs/surfaces/mackie/surface.h index 68b3c5f799..c0a2cff871 100644 --- a/libs/surfaces/mackie/surface.h +++ b/libs/surfaces/mackie/surface.h @@ -165,11 +165,11 @@ public: void display_message_for (std::string const& msg, uint64_t msecs); + bool connection_handler (boost::weak_ptr, std::string name1, boost::weak_ptr, std::string name2, bool); + XMLNode& get_state (); int set_state (const XMLNode&, int version); - protected: - private: MackieControlProtocol& _mcp; SurfacePort* _port; @@ -181,7 +181,6 @@ public: Mackie::JogWheel* _jog_wheel; Fader* _master_fader; float _last_master_gain_written; - PBD::ScopedConnection port_connection; void handle_midi_sysex (MIDI::Parser&, MIDI::byte *, size_t count); MidiByteArray host_connection_query (MidiByteArray& bytes); @@ -192,7 +191,6 @@ public: void init_strips (uint32_t n); void setup_master (); void master_gain_changed (); - void connection_handler (boost::weak_ptr, std::string name1, boost::weak_ptr, std::string name2, bool); enum ConnectionState { InputConnected = 0x1, -- cgit v1.2.3