CPM: Implement automatic ctrl-surface activision

This commit is contained in:
Robin Gareus 2023-05-01 05:16:45 +02:00
parent 65346496f5
commit 161d82869a
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
5 changed files with 55 additions and 2 deletions

View File

@ -74,6 +74,7 @@ class LIBARDOUR_API ControlProtocolManager : public PBD::Stateful, public ARDOUR
void foreach_known_protocol (boost::function<void(const ControlProtocolInfo*)>);
void midi_connectivity_established ();
void drop_protocols ();
void probe_midi_control_protocols ();
int activate (ControlProtocolInfo&);
int deactivate (ControlProtocolInfo&);

View File

@ -89,6 +89,7 @@ CONFIG_VARIABLE (float, ltc_output_volume, "ltc-output-volume", 0.125893)
CONFIG_VARIABLE (uint32_t, feedback_interval_ms, "feedback-interval-ms", 100)
CONFIG_VARIABLE (bool, use_tranzport, "use-tranzport", false)
CONFIG_VARIABLE (bool, auto_enable_surfaces, "auto-enable-surfaces", true)
/* disk operations */

View File

@ -2323,6 +2323,9 @@ private:
void setup_click_state (const XMLNode*);
void setup_bundles ();
void port_registry_changed ();
void probe_ctrl_surfaces ();
void save_as_bring_callback (uint32_t, uint32_t, std::string);
static const uint32_t session_end_shift;

View File

@ -382,6 +382,7 @@ ControlProtocolManager::control_protocol_discover (string path)
cpi->path = path;
cpi->protocol = 0;
cpi->requested = false;
cpi->automatic = false;
cpi->state = 0;
control_protocol_info.push_back (cpi);
@ -512,7 +513,7 @@ ControlProtocolManager::get_state () const
if ((*i)->protocol) {
XMLNode& child_state ((*i)->protocol->get_state());
child_state.set_property (X_("active"), true);
child_state.set_property (X_("active"), !(*i)->automatic);
delete ((*i)->state);
(*i)->state = new XMLNode (child_state);
root->add_child_nocopy (child_state);
@ -553,6 +554,38 @@ ControlProtocolManager::midi_connectivity_established ()
}
}
void
ControlProtocolManager::probe_midi_control_protocols ()
{
if (!Config->get_auto_enable_surfaces ()) {
return;
}
for (auto const& cpi : control_protocol_info) {
/* Note: manual teardown deletes the descriptor */
if (!cpi->descriptor) {
cpi->automatic = false;
continue;
}
if (!cpi->descriptor->probe_port) {
continue;
}
bool active = 0 != cpi->protocol;
bool found = cpi->descriptor->probe_port ();
if (!active && found) {
cpi->automatic = true;
activate (*cpi);
} else if (active && cpi->automatic && !found) {
cpi->automatic = false;
deactivate (*cpi);
/* allow to auto-enable again */
if (!cpi->descriptor) {
cpi->descriptor = get_descriptor (cpi->path);
}
}
}
}
void
ControlProtocolManager::stripable_selection_changed (StripableNotificationListPtr sp)
{

View File

@ -597,7 +597,7 @@ Session::immediately_post_engine ()
/* TODO, connect in different thread. (PortRegisteredOrUnregistered may be in RT context)
* can we do that? */
_engine.PortRegisteredOrUnregistered.connect_same_thread (*this, boost::bind (&Session::setup_bundles, this));
_engine.PortRegisteredOrUnregistered.connect_same_thread (*this, boost::bind (&Session::port_registry_changed, this));
_engine.PortPrettyNameChanged.connect_same_thread (*this, boost::bind (&Session::setup_bundles, this));
// set samplerate for plugins added early
@ -871,6 +871,21 @@ Session::destroy ()
BOOST_SHOW_POINTERS ();
}
void
Session::port_registry_changed()
{
setup_bundles ();
_butler->delegate (boost::bind (&Session::probe_ctrl_surfaces, this));
}
void
Session::probe_ctrl_surfaces()
{
if (!_engine.running() || deletion_in_progress ()) {
return;
}
ControlProtocolManager::instance ().probe_midi_control_protocols ();
}
void
Session::block_processing()