summaryrefslogtreecommitdiff
path: root/libs/ardour/jack_portengine.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libs/ardour/jack_portengine.cc')
-rw-r--r--libs/ardour/jack_portengine.cc253
1 files changed, 211 insertions, 42 deletions
diff --git a/libs/ardour/jack_portengine.cc b/libs/ardour/jack_portengine.cc
index b2534d47f5..4a6f3a1fca 100644
--- a/libs/ardour/jack_portengine.cc
+++ b/libs/ardour/jack_portengine.cc
@@ -1,5 +1,60 @@
-JACKPortEngine::init ()
+#define GET_PRIVATE_JACK_POINTER(localvar) jack_client_t* localvar = _jack_connection->jack(); if (!(localvar)) { return; }
+#define GET_PRIVATE_JACK_POINTER_RET(localvar,r) jack_client_t* localvar = _jack_connection->jack(); if (!(localvar)) { return r; }
+
+static uint32_t
+ardour_port_flags_to_jack_flags (PortFlags flags)
+{
+ uint32_t jack_flags = 0;
+
+ if (flags & PortIsInput) {
+ jack_flags |= JackPortIsInput;
+ }
+ if (flags & IsInput) {
+ jack_flags |= JackPortIsOutput;
+ }
+ if (flags & IsOutput) {
+ jack_flags |= JackPortIsTerminal;
+ }
+ if (flags & IsPhysical) {
+ jack_flags |= JackPortIsPhysical;
+ }
+ if (flags & CanMonitor) {
+ jack_flags |= JackPortCanMonitor;
+ }
+
+ return jack_flags;
+}
+
+static DataType
+jack_port_type_to_ardour_data_type (const char* jack_type)
+{
+ if (strcmp (jack_type, JACK_DEFAULT_AUDIO_TYPE) == 0) {
+ return DataType::AUDIO;
+ } else if (strcmp (jack_type, JACK_DEFAULT_MIDI_TYPE) == 0) {
+ return DataType::MIDI;
+ }
+ return DataType::NIL;
+}
+
+static const char*
+ardour_data_type_to_jack_port_type (DataType d)
{
+ switch (d) {
+ case DataType::AUDIO:
+ return JACK_DEFAULT_AUDIO_TYPE;
+ case DataType::MIDI:
+ return JACK_DEFAULT_MIDI_TYPE;
+ }
+
+ return "";
+}
+
+JACKPortEngine::JACKPortEngine (PortManager& pm, boost::shared_ptr<JackConnection> jc)
+ : PortEngine (pm)
+ , _jack_connection (jc)
+{
+ jack_client_t* client = _jack_connection->
+
jack_set_port_registration_callback (_priv_jack, _registration_callback, this);
jack_set_port_connect_callback (_priv_jack, _connect_callback, this);
jack_set_graph_order_callback (_priv_jack, _graph_order_callback, this);
@@ -8,67 +63,46 @@ JACKPortEngine::init ()
void
JACKPortEngine::_registration_callback (jack_port_id_t /*id*/, int /*reg*/, void* arg)
{
- JACKPortEngine* pm = static_cast<JACKAudioBackend*> (arg);
-
- if (!pm->port_remove_in_progress) {
- pm->engine.PortRegisteredOrUnregistered (); /* EMIT SIGNAL */
- }
+ static_cast<JACKPortEngine*> (arg)->_manager->registration_callback ();
}
void
JACKPortEngine::_connect_callback (jack_port_id_t id_a, jack_port_id_t id_b, int conn, void* arg)
{
- JACKPortEngine* pm = static_cast<JACKAudioBackend*> (arg);
- pm->connect_callback (id_a, id_b, conn);
+ static_cast<JACKPortEngine*> (arg)->connect_callback (id_a, id_b, conn);
}
void
JACKPortEngine::connect_callback (jack_port_id_t id_a, jack_port_id_t id_b, int conn)
{
- if (port_remove_in_progress) {
+ if (_manager->port_remove_in_progress()) {
return;
}
GET_PRIVATE_JACK_POINTER (_priv_jack);
- jack_port_t* jack_port_a = jack_port_by_id (_priv_jack, id_a);
- jack_port_t* jack_port_b = jack_port_by_id (_priv_jack, id_b);
+ jack_port_t* a = jack_port_by_id (_priv_jack, id_a);
+ jack_port_t* b = jack_port_by_id (_priv_jack, id_b);
- boost::shared_ptr<Port> port_a;
- boost::shared_ptr<Port> port_b;
- Ports::iterator x;
- boost::shared_ptr<Ports> pr = ports.reader ();
-
- x = pr->find (make_port_name_relative (jack_port_name (jack_port_a)));
- if (x != pr->end()) {
- port_a = x->second;
- }
-
- x = pr->find (make_port_name_relative (jack_port_name (jack_port_b)));
- if (x != pr->end()) {
- port_b = x->second;
- }
-
- PortConnectedOrDisconnected (
- port_a, jack_port_name (jack_port_a),
- port_b, jack_port_name (jack_port_b),
- conn == 0 ? false : true
- ); /* EMIT SIGNAL */
+ _manager->connect_callback (jack_port_name (a), jack_port_name (b), conn == 0 ? false : true);
}
int
JACKPortEngine::_graph_order_callback (void *arg)
{
- JACKPortEngine* pm = static_cast<JACKAudioBackend*> (arg);
+ return static_cast<JACKPortEngine*> (arg)->graph_order_callback ();
+}
- if (pm->connected() && !pm->port_remove_in_progress) {
- pm->engine.GraphReordered (); /* EMIT SIGNAL */
+int
+JACKPortEngine::graph_order_callback ()
+{
+ if (_jack_connection->connected()) {
+ _manager->graph_order_callback ();
}
-
+
return 0;
}
-
JACKPortEngine::physically_connected (PortHandle p)
{
jack_port_t* _jack_port = (jack_port_t*) p;
@@ -102,13 +136,148 @@ JACKPortEngine::physically_connected (PortHandle p)
DataType
JACKPortEngine::port_data_type (PortHandle p)
{
- const char* t = jack_port_type (p);
+ return jack_port_type_to_ardour_data_type (jack_port_type (p));
+}
- if (strcmp (p, JACK_DEFAULT_AUDIO_TYPE) == 0) {
- return DataType::AUDIO;
- } else if (strcmp (p, JACK_DEFAULT_MIDI_TYPE) == 0) {
- return DataType::MIDI;
+const string&
+JACKPortEngine::my_name() const
+{
+ return _client_name;
+}
+
+bool
+JACKPortEngine::port_is_physical (PortHandle* ph) const
+{
+ if (!ph) {
+ return false;
+ }
+
+ return jack_port_flags (ph) & JackPortIsPhysical;
+}
+
+int
+JACKPortEngine::get_ports (const string& port_name_pattern, DataType type, PortFlags flags, vector<string>& s)
+{
+
+ GET_PRIVATE_JACK_POINTER_RET (_priv_jack,0);
+
+ const char** ports = jack_get_ports (_priv_jack, port_name_pattern.c_str(),
+ ardour_data_type_to_jack_port_type (type),
+ ardour_port_flags_to_jack_flags (flags));
+
+ if (ports == 0) {
+ return s;
}
- return DataType::NIL;
+ for (uint32_t i = 0; ports[i]; ++i) {
+ s.push_back (ports[i]);
+ jack_free (ports[i]);
+ }
+
+ jack_free (ports);
+
+ return s.size();
+}
+
+ChanCount
+JACKPortEngine::n_physical (unsigned long flags) const
+{
+ ChanCount c;
+
+ GET_PRIVATE_JACK_POINTER_RET (_jack, c);
+
+ const char ** ports = jack_get_ports (_priv_jack, NULL, NULL, JackPortIsPhysical | flags);
+
+ if (ports) {
+ for (uint32_t i = 0; ports[i]; ++i) {
+ if (!strstr (ports[i], "Midi-Through")) {
+ DataType t (jack_port_type (jack_port_by_name (_jack, ports[i])));
+ c.set (t, c.get (t) + 1);
+ jack_free (ports[i]);
+ }
+ }
+
+ jack_free (ports);
+ }
+
+ return c;
+}
+
+ChanCount
+JACKPortEngine::n_physical_inputs () const
+{
+ return n_physical (JackPortIsInput);
+}
+
+ChanCount
+JACKPortEngine::n_physical_outputs () const
+{
+ return n_physical (JackPortIsOutput);
+}
+
+void
+JACKPortEngine::get_physical (DataType type, unsigned long flags, vector<string>& phy)
+{
+ GET_PRIVATE_JACK_POINTER (_priv_jack);
+ const char ** ports;
+
+ if ((ports = jack_get_ports (_priv_jack, NULL, type.to_jack_type(), JackPortIsPhysical | flags)) == 0) {
+ return;
+ }
+
+ if (ports) {
+ for (uint32_t i = 0; ports[i]; ++i) {
+ if (strstr (ports[i], "Midi-Through")) {
+ continue;
+ }
+ phy.push_back (ports[i]);
+ jack_free (ports[i]);
+ }
+ jack_free (ports);
+ }
+}
+
+/** Get physical ports for which JackPortIsOutput is set; ie those that correspond to
+ * a physical input connector.
+ */
+void
+JACKPortEngine::get_physical_inputs (DataType type, vector<string>& ins)
+{
+ get_physical (type, JackPortIsOutput, ins);
+}
+
+/** Get physical ports for which JackPortIsInput is set; ie those that correspond to
+ * a physical output connector.
+ */
+void
+JACKPortEngine::get_physical_outputs (DataType type, vector<string>& outs)
+{
+ get_physical (type, JackPortIsInput, outs);
+}
+
+
+bool
+JACKPortEngine::can_request_hardware_monitoring ()
+{
+ GET_PRIVATE_JACK_POINTER_RET (_priv_jack,false);
+ const char ** ports;
+
+ if ((ports = jack_get_ports (_priv_jack, NULL, JACK_DEFAULT_AUDIO_TYPE, JackPortCanMonitor)) == 0) {
+ return false;
+ }
+
+ for (uint32_t i = 0; ports[i]; ++i) {
+ jack_free (ports[i]);
+ }
+
+ jack_free (ports);
+
+ return true;
+}
+
+framecnt_t
+JACKPortEngine::last_frame_time () const
+{
+ GET_PRIVATE_JACK_POINTER_RET (_priv_jack, 0);
+ return jack_last_frame_time (_priv_jack);
}