From 5dce10500cc09dfa703f5b6e90efd5ff9ba0936e Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Tue, 18 Apr 2017 15:14:00 +0200 Subject: [PATCH] FP8: handle backend changes + reconnect When the backend is dropped or changed, on engine-restart the connection_handler() re-establishes already connected ports. There's no disconnect when the backend dies or is hard-stopped. --- libs/surfaces/faderport8/faderport8.cc | 41 ++++++++++++++++++++++---- libs/surfaces/faderport8/faderport8.h | 5 ++-- 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/libs/surfaces/faderport8/faderport8.cc b/libs/surfaces/faderport8/faderport8.cc index 802942cbe7..be5f60a824 100644 --- a/libs/surfaces/faderport8/faderport8.cc +++ b/libs/surfaces/faderport8/faderport8.cc @@ -124,7 +124,9 @@ FaderPort8::FaderPort8 (Session& s) session->engine().make_port_name_non_relative (outp->name()) ); - ARDOUR::AudioEngine::instance()->PortConnectedOrDisconnected.connect (port_connection, MISSING_INVALIDATOR, boost::bind (&FaderPort8::connection_handler, this, _1, _2, _3, _4, _5), this); + ARDOUR::AudioEngine::instance()->PortConnectedOrDisconnected.connect (port_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort8::connection_handler, this, _2, _4), this); + ARDOUR::AudioEngine::instance()->Stopped.connect (port_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort8::engine_reset, this), this); + ARDOUR::Port::PortDrop.connect (port_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort8::engine_reset, this), this); StripableSelectionChanged.connect (selection_connection, MISSING_INVALIDATOR, boost::bind (&FaderPort8::gui_track_selection_changed, this), this); @@ -265,13 +267,14 @@ FaderPort8::set_active (bool yn) void FaderPort8::close () { + DEBUG_TRACE (DEBUG::FaderPort8, "FaderPort8::close\n"); stop_midi_handling (); session_connections.drop_connections (); automation_state_connections.drop_connections (); assigned_stripable_connections.drop_connections (); _assigned_strips.clear (); drop_ctrl_connections (); - port_connection.disconnect (); + port_connections.drop_connections (); selection_connection.disconnect (); } @@ -290,6 +293,12 @@ void FaderPort8::connected () { DEBUG_TRACE (DEBUG::FaderPort8, "initializing\n"); + assert (!_device_active); + + if (_device_active) { + stop_midi_handling (); // re-init + } + // ideally check firmware version >= 1.01 (USB bcdDevice 0x0101) (vendor 0x194f prod 0x0202) // but we don't have a handle to the underlying USB device here. @@ -336,8 +345,18 @@ FaderPort8::disconnected () } } +void +FaderPort8::engine_reset () +{ + /* Port::PortDrop is called when the engine is halted or stopped */ + DEBUG_TRACE (DEBUG::FaderPort8, "FaderPort8::engine_reset\n"); + _connection_state = 0; + _device_active = false; + disconnected (); +} + bool -FaderPort8::connection_handler (boost::weak_ptr, std::string name1, boost::weak_ptr, std::string name2, bool yn) +FaderPort8::connection_handler (std::string name1, std::string name2) { #ifdef VERBOSE_DEBUG DEBUG_TRACE (DEBUG::FaderPort8, "FaderPort8::connection_handler: start\n"); @@ -350,13 +369,21 @@ FaderPort8::connection_handler (boost::weak_ptr, std::string name1 string no = ARDOUR::AudioEngine::instance()->make_port_name_non_relative (boost::shared_ptr(_output_port)->name()); if (ni == name1 || ni == name2) { - if (yn) { + DEBUG_TRACE (DEBUG::FaderPort8, string_compose ("Connection notify %1 and %2\n", name1, name2)); + if (_input_port->connected ()) { + if (_connection_state & InputConnected) { + return false; + } _connection_state |= InputConnected; } else { _connection_state &= ~InputConnected; } } else if (no == name1 || no == name2) { - if (yn) { + DEBUG_TRACE (DEBUG::FaderPort8, string_compose ("Connection notify %1 and %2\n", name1, name2)); + if (_output_port->connected ()) { + if (_connection_state & OutputConnected) { + return false; + } _connection_state |= OutputConnected; } else { _connection_state &= ~OutputConnected; @@ -382,7 +409,9 @@ FaderPort8::connection_handler (boost::weak_ptr, std::string name1 } else { DEBUG_TRACE (DEBUG::FaderPort8, "Device disconnected (input or output or both) or not yet fully connected\n"); - disconnected (); + if (_device_active) { + disconnected (); + } _device_active = false; } diff --git a/libs/surfaces/faderport8/faderport8.h b/libs/surfaces/faderport8/faderport8.h index e258612bcc..00ffe827df 100644 --- a/libs/surfaces/faderport8/faderport8.h +++ b/libs/surfaces/faderport8/faderport8.h @@ -100,7 +100,7 @@ private: void stop_midi_handling (); /* I/O Ports */ - PBD::ScopedConnection port_connection; + PBD::ScopedConnectionList port_connections; boost::shared_ptr _input_port; boost::shared_ptr _output_port; boost::shared_ptr _input_bundle; @@ -108,7 +108,8 @@ private: bool midi_input_handler (Glib::IOCondition ioc, boost::weak_ptr port); - bool connection_handler (boost::weak_ptr, std::string name1, boost::weak_ptr, std::string name2, bool yn); + bool connection_handler (std::string name1, std::string name2); + void engine_reset (); enum ConnectionState { InputConnected = 0x1, -- 2.30.2