summaryrefslogtreecommitdiff
path: root/libs/ardour
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2019-03-07 12:00:51 -0700
committerPaul Davis <paul@linuxaudiosystems.com>2019-03-07 12:01:27 -0700
commitf7802325dcf07b6dec4061d0bd413ed6f09a4e8c (patch)
tree4fc8987efc566a64f4eb2f55be4fcfa5abb7ceac /libs/ardour
parent8b212bfa1294aa0e751690de355b05d4eaa82759 (diff)
redesign naming and reload of MIDI port information (library edition)
Diffstat (limited to 'libs/ardour')
-rw-r--r--libs/ardour/ardour/port_manager.h11
-rw-r--r--libs/ardour/port_manager.cc131
2 files changed, 94 insertions, 48 deletions
diff --git a/libs/ardour/ardour/port_manager.h b/libs/ardour/ardour/port_manager.h
index e2a932e0d9..268c166b13 100644
--- a/libs/ardour/ardour/port_manager.h
+++ b/libs/ardour/ardour/port_manager.h
@@ -101,6 +101,8 @@ class LIBARDOUR_API PortManager
int get_ports (const std::string& port_name_pattern, DataType type, PortFlags flags, std::vector<std::string>&);
int get_ports (DataType, PortList&);
+ void set_port_pretty_name (std::string const&, std::string const&);
+
void remove_all_ports ();
void clear_pending_port_deletions ();
virtual void add_pending_port_deletion (Port*) = 0;
@@ -134,11 +136,17 @@ class LIBARDOUR_API PortManager
bool port_remove_in_progress() const { return _port_remove_in_progress; }
struct MidiPortInformation {
+ std::string canonical_name;
std::string pretty_name;
bool input;
MidiPortFlags properties;
+ bool exists;
- MidiPortInformation () : input (false) , properties (MidiPortFlags (0)) {}
+ MidiPortInformation (std::string const & canonical, bool input, MidiPortFlags flags, bool xists)
+ : canonical_name (canonical)
+ , input (input)
+ , properties (flags)
+ , exists (xists) {}
};
void fill_midi_port_info ();
@@ -148,7 +156,6 @@ class LIBARDOUR_API PortManager
void get_midi_selection_ports (std::vector<std::string>&);
void add_midi_port_flags (std::string const&, MidiPortFlags);
void remove_midi_port_flags (std::string const&, MidiPortFlags);
- void set_midi_port_pretty_name (std::string const&, std::string const&);
/** Emitted if the list of ports to be used for MIDI selection tracking changes */
PBD::Signal0<void> MidiSelectionPortsChanged;
diff --git a/libs/ardour/port_manager.cc b/libs/ardour/port_manager.cc
index 85aa9819d6..ae0dd5d838 100644
--- a/libs/ardour/port_manager.cc
+++ b/libs/ardour/port_manager.cc
@@ -17,6 +17,8 @@
*/
+#include <vector>
+
#ifdef COMPILER_MSVC
#include <io.h> // Microsoft's nearest equivalent to <unistd.h>
#include <ardourext/misc.h>
@@ -28,6 +30,7 @@
#include <glibmm/miscutils.h>
#include "pbd/error.h"
+#include "pbd/strsplit.h"
#include "ardour/async_midi_port.h"
#include "ardour/audio_backend.h"
@@ -49,6 +52,8 @@ using namespace PBD;
using std::string;
using std::vector;
+#define MIDI_PORT_INFO_SEPARATOR_CHAR '!'
+
PortManager::PortManager ()
: ports (new Ports)
, _port_remove_in_progress (false)
@@ -143,17 +148,16 @@ std::string
PortManager::get_pretty_name_by_name(const std::string& portname) const
{
PortEngine::PortHandle ph = _backend->get_port_by_name (portname);
+
if (ph) {
std::string value;
std::string type;
- if (0 == _backend->get_port_property (ph,
- "http://jackaudio.org/metadata/pretty-name",
- value, type))
- {
+ if (0 == _backend->get_port_property (ph, "http://jackaudio.org/metadata/pretty-name", value, type)) {
return value;
}
}
- return "";
+
+ return string();
}
bool
@@ -1010,7 +1014,7 @@ PortManager::midi_port_information (std::string const & name)
return x->second;
}
- return MidiPortInformation ();
+ return MidiPortInformation (string(), false, MidiPortFlags(0), false);
}
void
@@ -1040,8 +1044,9 @@ PortManager::get_midi_selection_ports (vector<string>& copy)
}
void
-PortManager::set_midi_port_pretty_name (string const & port, string const & pretty)
+PortManager::set_port_pretty_name (string const & port, string const & pretty)
{
+ bool emit = false;
{
Glib::Threads::Mutex::Lock lm (midi_port_info_mutex);
@@ -1052,6 +1057,7 @@ PortManager::set_midi_port_pretty_name (string const & port, string const & pret
return;
}
x->second.pretty_name = pretty;
+ emit = true;
}
/* push into back end */
@@ -1062,7 +1068,9 @@ PortManager::set_midi_port_pretty_name (string const & port, string const & pret
_backend->set_port_property (ph, "http://jackaudio.org/metadata/pretty-name", pretty, string());
}
- MidiPortInfoChanged (); /* EMIT SIGNAL*/
+ if (emit) {
+ MidiPortInfoChanged (); /* EMIT SIGNAL*/
+ }
}
void
@@ -1153,6 +1161,7 @@ PortManager::save_midi_port_info ()
for (MidiPortInfo::iterator i = midi_port_info.begin(); i != midi_port_info.end(); ++i) {
XMLNode* node = new XMLNode (X_("port"));
node->set_property (X_("name"), i->first);
+ node->set_property (X_("canonical-name"), i->second.canonical_name);
node->set_property (X_("input"), i->second.input);
node->set_property (X_("properties"), i->second.properties);
root->add_child_nocopy (*node);
@@ -1186,15 +1195,21 @@ PortManager::load_midi_port_info ()
midi_port_info.clear ();
for (XMLNodeConstIterator i = tree.root()->children().begin(); i != tree.root()->children().end(); ++i) {
- MidiPortInformation mpi;
string name;
+ string canonical;
+ bool input;
+ MidiPortFlags properties;
+
if (!(*i)->get_property (X_("name"), name) ||
- !(*i)->get_property (X_("input"), mpi.input) ||
- !(*i)->get_property (X_("properties"), mpi.properties)) {
+ !(*i)->get_property (X_("canonical-name"), canonical) ||
+ !(*i)->get_property (X_("input"), input) ||
+ !(*i)->get_property (X_("properties"), properties)) {
continue;
}
+ MidiPortInformation mpi (canonical, input, properties, false);
+
midi_port_info.insert (make_pair (name, mpi));
}
}
@@ -1202,8 +1217,12 @@ PortManager::load_midi_port_info ()
void
PortManager::fill_midi_port_info ()
{
- Glib::Threads::Mutex::Lock lm (midi_port_info_mutex);
- fill_midi_port_info_locked ();
+ {
+ Glib::Threads::Mutex::Lock lm (midi_port_info_mutex);
+ fill_midi_port_info_locked ();
+ }
+
+ save_midi_port_info ();
}
void
@@ -1211,7 +1230,7 @@ PortManager::fill_midi_port_info_locked ()
{
/* MIDI info mutex MUST be held */
- if (!midi_info_dirty) {
+ if (!midi_info_dirty || !_backend) {
return;
}
@@ -1226,17 +1245,20 @@ PortManager::fill_midi_port_info_locked ()
}
if (midi_port_info.find (*p) == midi_port_info.end()) {
- MidiPortInformation mpi;
- mpi.pretty_name = *p;
- mpi.input = true;
+
+ MidiPortFlags flags (MidiPortFlags (0));
if (port_is_control_only (*p)) {
- mpi.properties = MidiPortFlags (mpi.properties | MidiPortControl);
+ flags = MidiPortControl;
}
+
+ MidiPortInformation mpi (string_compose ("%1%4%2%4%3", _backend->name(), _backend->device_name(), *p, MIDI_PORT_INFO_SEPARATOR_CHAR),
+ true,
+ flags,
+ true);
+
#ifdef LINUX
- if ((*p.find (X_("Midi Through")) != string::npos ||
- (*p).find (X_("Midi-Through")) != string::npos))
- {
+ if ((*p.find (X_("Midi Through")) != string::npos || (*p).find (X_("Midi-Through")) != string::npos)) {
mpi.properties = MidiPortFlags (mpi.properties | MidiPortVirtual);
}
#endif
@@ -1253,17 +1275,20 @@ PortManager::fill_midi_port_info_locked ()
}
if (midi_port_info.find (*p) == midi_port_info.end()) {
- MidiPortInformation mpi;
- mpi.pretty_name = *p;
- mpi.input = false;
+
+ MidiPortFlags flags (MidiPortFlags (0));
if (port_is_control_only (*p)) {
- mpi.properties = MidiPortFlags (mpi.properties | MidiPortControl);
+ flags = MidiPortControl;
}
+
+ MidiPortInformation mpi (string_compose ("%1%4%2%4%3", _backend->name(), _backend->device_name(), *p, MIDI_PORT_INFO_SEPARATOR_CHAR),
+ false,
+ flags,
+ true);
+
#ifdef LINUX
- if ((*p.find (X_("Midi Through")) != string::npos ||
- (*p).find (X_("Midi-Through")) != string::npos))
- {
+ if ((*p.find (X_("Midi Through")) != string::npos || (*p).find (X_("Midi-Through")) != string::npos)) {
mpi.properties = MidiPortFlags (mpi.properties | MidiPortVirtual);
}
#endif
@@ -1271,35 +1296,49 @@ PortManager::fill_midi_port_info_locked ()
}
}
- /* now push/pull pretty name information between backend and the
- * PortManager
+ /* now check with backend about which ports are present and pull
+ * pretty-name if it exists
*/
- // rg: I don't understand what this attempts to solve
- //
- // Naming ports should be left to the backend:
- // Ardour cannot associate numeric IDs with corresponding hardware.
- // (see also 7dde6c3b)
-
for (MidiPortInfo::iterator x = midi_port_info.begin(); x != midi_port_info.end(); ++x) {
- PortEngine::PortHandle ph = _backend->get_port_by_name (x->first);
+
+ vector<string> parts;
+
+ /*PBD::*/split (x->second.canonical_name, parts, MIDI_PORT_INFO_SEPARATOR_CHAR);
+ assert (parts.size() == 3);
+
+ if (parts[0] != _backend->name()) {
+ x->second.exists = false;
+ continue;
+ }
+
+ if (parts[1] != _backend->device_name()) {
+ x->second.exists = false;
+ continue;
+ }
+
+ PortEngine::PortHandle ph = _backend->get_port_by_name (parts[2]);
if (!ph) {
/* port info saved from some condition where this port
* existed, but no longer does (i.e. device unplugged
* at present). We don't remove it from midi_port_info.
*/
- continue;
- }
+ x->second.exists = false;
- /* check with backend for pre-existing pretty name */
- string value;
- string type;
+ } else {
+ x->second.exists = true;
+ /* check with backend for pre-existing pretty name */
+
+ string value;
+
+ value = AudioEngine::instance()->get_pretty_name_by_name (x->first);
- if (0 == _backend->get_port_property (ph,
- "http://jackaudio.org/metadata/pretty-name",
- value, type)) {
- x->second.pretty_name = value;
+ if (!value.empty()) {
+ x->second.pretty_name = value;
+ } else {
+ x->second.pretty_name = parts[2];
+ }
}
}