From 6866359c4800a3443f218c8c3fcff08f83fea9da Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Fri, 21 Oct 2016 16:32:46 -0400 Subject: [PATCH] when fetching MIDI ports for bundles and auto-connection, ignore control-only (and "virtual") MIDI ports "virtual" is a placeholder name for ALSA sequencer MIDI through ports --- libs/ardour/ardour/port_manager.h | 10 ++++- libs/ardour/ardour/session.h | 4 +- libs/ardour/ardour/types.h | 1 + libs/ardour/port_manager.cc | 65 ++++++++++++++++++++++++++++++- libs/ardour/session.cc | 48 +++++++---------------- 5 files changed, 90 insertions(+), 38 deletions(-) diff --git a/libs/ardour/ardour/port_manager.h b/libs/ardour/ardour/port_manager.h index f7b0034890..4b95d2ca6e 100644 --- a/libs/ardour/ardour/port_manager.h +++ b/libs/ardour/ardour/port_manager.h @@ -89,8 +89,12 @@ class LIBARDOUR_API PortManager /* other Port management */ bool port_is_physical (const std::string&) const; - void get_physical_outputs (DataType type, std::vector&); - void get_physical_inputs (DataType type, std::vector&); + void get_physical_outputs (DataType type, std::vector&, + MidiPortFlags include = MidiPortFlags (0), + MidiPortFlags exclude = MidiPortFlags (0)); + void get_physical_inputs (DataType type, std::vector&, + MidiPortFlags include = MidiPortFlags (0), + MidiPortFlags exclude = MidiPortFlags (0)); ChanCount n_physical_outputs () const; ChanCount n_physical_inputs () const; @@ -204,6 +208,8 @@ class LIBARDOUR_API PortManager void save_midi_port_info (); void load_midi_port_info (); void fill_midi_port_info_locked (); + + void filter_midi_ports (std::vector&, MidiPortFlags, MidiPortFlags); }; diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 6d05af8beb..f37746d6b2 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -1532,7 +1532,9 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop AutoConnectQueue _auto_connect_queue; guint _latency_recompute_pending; - void get_physical_ports (std::vector& inputs, std::vector& outputs, DataType type, bool excluding); + void get_physical_ports (std::vector& inputs, std::vector& outputs, DataType type, + MidiPortFlags include = MidiPortFlags (0), + MidiPortFlags exclude = MidiPortFlags (0)); void auto_connect (const AutoConnectRequest&); void queue_latency_recompute (); diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h index cf21e4c11b..612ca9aa3f 100644 --- a/libs/ardour/ardour/types.h +++ b/libs/ardour/ardour/types.h @@ -664,6 +664,7 @@ namespace ARDOUR { MidiPortMusic = 0x1, MidiPortControl = 0x2, MidiPortSelection = 0x4, + MidiPortVirtual = 0x8 }; struct LatencyRange { diff --git a/libs/ardour/port_manager.cc b/libs/ardour/port_manager.cc index ca980c0294..a7341c442d 100644 --- a/libs/ardour/port_manager.cc +++ b/libs/ardour/port_manager.cc @@ -189,17 +189,55 @@ PortManager::port_is_physical (const std::string& portname) const } void -PortManager::get_physical_outputs (DataType type, std::vector& s) +PortManager::filter_midi_ports (vector& ports, MidiPortFlags include, MidiPortFlags exclude) +{ + if (!include && !exclude) { + return; + } + + for (vector::iterator si = ports.begin(); si != ports.end(); ) { + + PortManager::MidiPortInformation mpi = midi_port_information (*si); + + if (mpi.pretty_name.empty()) { + /* no information !!! */ + ++si; + continue; + } + + if (include) { + if ((mpi.properties & include) != include) { + /* properties do not include requested ones */ + si = ports.erase (si); + continue; + } + } + + if (exclude) { + if ((mpi.properties & exclude)) { + /* properties include ones to avoid */ + si = ports.erase (si); + continue; + } + } + + ++si; + } +} + +void +PortManager::get_physical_outputs (DataType type, std::vector& s, MidiPortFlags include, MidiPortFlags exclude) { if (!_backend) { s.clear (); return; } _backend->get_physical_outputs (type, s); + filter_midi_ports (s, include, exclude); } void -PortManager::get_physical_inputs (DataType type, std::vector& s) +PortManager::get_physical_inputs (DataType type, std::vector& s, MidiPortFlags include, MidiPortFlags exclude) { if (!_backend) { s.clear (); @@ -207,6 +245,7 @@ PortManager::get_physical_inputs (DataType type, std::vector& s) } _backend->get_physical_inputs (type, s); + filter_midi_ports (s, include, exclude); } ChanCount @@ -1124,6 +1163,17 @@ PortManager::fill_midi_port_info_locked () MidiPortInformation mpi; mpi.pretty_name = *p; mpi.input = true; + + if (port_is_control_only (*p)) { + mpi.properties = MidiPortFlags (mpi.properties | MidiPortControl); + } +#ifdef LINUX + if ((*p.find (X_("Midi Through")) != string::npos || + (*p).find (X_("Midi-Through")) != string::npos)) + { + mpi.properties = MidiPortFlags (mpi.properties | MidiPortVirtual); + } +#endif midi_port_info.insert (make_pair (*p, mpi)); } } @@ -1140,6 +1190,17 @@ PortManager::fill_midi_port_info_locked () MidiPortInformation mpi; mpi.pretty_name = *p; mpi.input = false; + + if (port_is_control_only (*p)) { + mpi.properties = MidiPortFlags (mpi.properties | MidiPortControl); + } +#ifdef LINUX + if ((*p.find (X_("Midi Through")) != string::npos || + (*p).find (X_("Midi-Through")) != string::npos)) + { + mpi.properties = MidiPortFlags (mpi.properties | MidiPortVirtual); + } +#endif midi_port_info.insert (make_pair (*p, mpi)); } } diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 8313c215ef..5605ac1e6c 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -912,38 +912,11 @@ Session::setup_click_state (const XMLNode* node) } void -Session::get_physical_ports (vector& inputs, vector& outputs, DataType type, bool excluding) +Session::get_physical_ports (vector& inputs, vector& outputs, DataType type, + MidiPortFlags include, MidiPortFlags exclude) { - _engine.get_physical_inputs (type, inputs); - - if (excluding) { - /* rip out ControlOnly ports, and ALSA MIDI Through ports */ - - for (vector::iterator si = inputs.begin(); si != inputs.end(); ) { - if (PortManager::port_is_control_only (*si)) { - si = inputs.erase (si); - } else if ((*si).find (X_("Midi Through")) != string::npos || (*si).find (X_("Midi-Through")) != string::npos) { - si = inputs.erase (si); - } else { - ++si; - } - } - } - _engine.get_physical_outputs (type, outputs); - - if (excluding) { - /* rip out ControlOnly ports, and ALSA MIDI Through ports */ - - for (vector::iterator si = outputs.begin(); si != outputs.end(); ) { - if (PortManager::port_is_control_only (*si)) { - si = outputs.erase (si); - } else if ((*si).find (X_("Midi Through")) != string::npos || (*si).find (X_("Midi-Through")) != string::npos) { - si = outputs.erase (si); - } else { - ++si; - } - } - } + _engine.get_physical_inputs (type, inputs, include, exclude); + _engine.get_physical_outputs (type, outputs, include, exclude); } void @@ -966,7 +939,10 @@ Session::setup_bundles () vector outputs[DataType::num_types]; for (uint32_t i = 0; i < DataType::num_types; ++i) { - get_physical_ports (inputs[i], outputs[i], DataType (DataType::Symbol (i)), true); + get_physical_ports (inputs[i], outputs[i], DataType (DataType::Symbol (i)), + MidiPortFlags (0), /* no specific inclusions */ + MidiPortFlags (MidiPortControl|MidiPortVirtual) /* exclude control & virtual ports */ + ); } /* Create a set of Bundle objects that map @@ -1050,6 +1026,7 @@ Session::setup_bundles () for (uint32_t np = 0; np < inputs[DataType::MIDI].size(); ++np) { string n = inputs[DataType::MIDI][np]; + std::string pn = _engine.get_pretty_name_by_name (n); if (!pn.empty()) { n = pn; @@ -6954,7 +6931,12 @@ Session::auto_connect (const AutoConnectRequest& ar) vector physinputs; vector physoutputs; - get_physical_ports (physinputs, physoutputs, *t, true); + + /* for connecting track inputs we only want MIDI ports marked + * for "music". + */ + + get_physical_ports (physinputs, physoutputs, *t, MidiPortMusic); if (!physinputs.empty() && ar.connect_inputs) { uint32_t nphysical_in = physinputs.size();