summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/AlsaDriver.cpp71
-rw-r--r--src/ClientID.hpp4
-rw-r--r--src/JackDbusDriver.cpp16
-rw-r--r--src/JackDriver.cpp50
-rw-r--r--src/PatchageCanvas.cpp33
-rw-r--r--src/PatchageEvent.cpp4
-rw-r--r--src/PatchageEvent.hpp29
-rw-r--r--src/PatchagePort.hpp2
-rw-r--r--src/PortID.hpp153
9 files changed, 176 insertions, 186 deletions
diff --git a/src/AlsaDriver.cpp b/src/AlsaDriver.cpp
index 7cd4f8d..b8dcdc6 100644
--- a/src/AlsaDriver.cpp
+++ b/src/AlsaDriver.cpp
@@ -31,6 +31,16 @@ PATCHAGE_RESTORE_WARNINGS
#include <string>
#include <utility>
+namespace {
+
+inline PortID
+addr_to_id(const snd_seq_addr_t& addr, bool is_input)
+{
+ return PortID::alsa(addr.client, addr.port, is_input);
+}
+
+} // namespace
+
AlsaDriver::AlsaDriver(Patchage* app, ILog& log)
: _app(app)
, _log(log)
@@ -153,8 +163,8 @@ AlsaDriver::refresh()
continue;
}
- PatchagePort* port1 =
- _app->canvas()->find_port(PortID(*addr, false));
+ PatchagePort* const port1 = _app->canvas()->find_port(
+ PortID::alsa(addr->client, addr->port, false));
if (!port1) {
continue;
}
@@ -167,7 +177,8 @@ AlsaDriver::refresh()
const snd_seq_addr_t* addr2 =
snd_seq_query_subscribe_get_addr(subsinfo);
if (addr2) {
- const PortID id2(*addr2, true);
+ const PortID id2 =
+ PortID::alsa(addr2->client, addr2->port, true);
PatchagePort* port2 = _app->canvas()->find_port(id2);
if (port2 && !_app->canvas()->get_edge(port1, port2)) {
_app->canvas()->make_connection(port1, port2);
@@ -186,7 +197,8 @@ AlsaDriver::create_port_view(Patchage*, const PortID& id)
{
PatchageModule* parent = nullptr;
PatchagePort* port = nullptr;
- create_port_view_internal(id.id.alsa_addr, parent, port);
+ create_port_view_internal({id.alsa_client(), id.alsa_port()}, parent, port);
+
return port;
}
@@ -324,7 +336,7 @@ AlsaDriver::create_port(PatchageModule& parent,
bool is_input,
snd_seq_addr_t addr)
{
- const PortID id{addr, is_input};
+ const PortID id = PortID::alsa(addr.client, addr.port, is_input);
auto* ret =
new PatchagePort(parent,
@@ -401,14 +413,18 @@ AlsaDriver::connect(const PortID tail_id,
const std::string& head_client_name,
const std::string& head_port_name)
{
- if (tail_id.type != PortID::Type::alsa_addr ||
- head_id.type != PortID::Type::alsa_addr) {
+ if (tail_id.type() != PortID::Type::alsa ||
+ head_id.type() != PortID::Type::alsa) {
_log.error("[ALSA] Attempt to connect non-ALSA ports");
return false;
}
- const auto& tail_addr = tail_id.id.alsa_addr;
- const auto& head_addr = head_id.id.alsa_addr;
+ const snd_seq_addr_t tail_addr = {tail_id.alsa_client(),
+ tail_id.alsa_port()};
+
+ const snd_seq_addr_t head_addr = {head_id.alsa_client(),
+ head_id.alsa_port()};
+
if (tail_addr.client == head_addr.client &&
tail_addr.port == head_addr.port) {
_log.warning("[ALSA] Refusing to connect port to itself");
@@ -467,14 +483,17 @@ AlsaDriver::disconnect(const PortID tail_id,
const std::string& head_client_name,
const std::string& head_port_name)
{
- if (tail_id.type != PortID::Type::alsa_addr ||
- head_id.type != PortID::Type::alsa_addr) {
+ if (tail_id.type() != PortID::Type::alsa ||
+ head_id.type() != PortID::Type::alsa) {
_log.error("[ALSA] Attempt to disconnect non-ALSA ports");
return false;
}
- const auto& tail_addr = tail_id.id.alsa_addr;
- const auto& head_addr = head_id.id.alsa_addr;
+ const snd_seq_addr_t tail_addr = {tail_id.alsa_client(),
+ tail_id.alsa_port()};
+
+ const snd_seq_addr_t head_addr = {head_id.alsa_client(),
+ head_id.alsa_port()};
snd_seq_port_subscribe_t* subs = nullptr;
snd_seq_port_subscribe_malloc(&subs);
@@ -581,17 +600,19 @@ AlsaDriver::_refresh_main()
case SND_SEQ_EVENT_PORT_SUBSCRIBED:
if (!ignore(ev->data.connect.sender) &&
!ignore(ev->data.connect.dest)) {
- _events.push(PatchageEvent(PatchageEvent::Type::connection,
- ev->data.connect.sender,
- ev->data.connect.dest));
+ _events.push(
+ PatchageEvent(PatchageEvent::Type::connection,
+ addr_to_id(ev->data.connect.sender, false),
+ addr_to_id(ev->data.connect.dest, true)));
}
break;
case SND_SEQ_EVENT_PORT_UNSUBSCRIBED:
if (!ignore(ev->data.connect.sender) &&
!ignore(ev->data.connect.dest)) {
- _events.push(PatchageEvent(PatchageEvent::Type::disconnection,
- ev->data.connect.sender,
- ev->data.connect.dest));
+ _events.push(
+ PatchageEvent(PatchageEvent::Type::disconnection,
+ addr_to_id(ev->data.connect.sender, false),
+ addr_to_id(ev->data.connect.dest, true)));
}
break;
case SND_SEQ_EVENT_PORT_START:
@@ -603,7 +624,7 @@ AlsaDriver::_refresh_main()
if (!ignore(ev->data.addr)) {
_events.push(PatchageEvent(
PatchageEvent::Type::port_creation,
- PortID(ev->data.addr, (caps & SND_SEQ_PORT_CAP_READ))));
+ addr_to_id(ev->data.addr, (caps & SND_SEQ_PORT_CAP_READ))));
}
break;
case SND_SEQ_EVENT_PORT_EXIT:
@@ -612,15 +633,15 @@ AlsaDriver::_refresh_main()
// Delete both inputs and outputs (to handle duplex ports)
_events.push(
PatchageEvent(PatchageEvent::Type::port_destruction,
- PortID(ev->data.addr, true)));
+ addr_to_id(ev->data.addr, true)));
_events.push(
PatchageEvent(PatchageEvent::Type::port_destruction,
- PortID(ev->data.addr, false)));
+ addr_to_id(ev->data.addr, false)));
+ _port_addrs.erase(_app->canvas()->find_port(
+ addr_to_id(ev->data.addr, false)));
_port_addrs.erase(
- _app->canvas()->find_port(PortID(ev->data.addr, false)));
- _port_addrs.erase(
- _app->canvas()->find_port(PortID(ev->data.addr, true)));
+ _app->canvas()->find_port(addr_to_id(ev->data.addr, true)));
}
break;
case SND_SEQ_EVENT_CLIENT_CHANGE:
diff --git a/src/ClientID.hpp b/src/ClientID.hpp
index 665c237..d58c5ee 100644
--- a/src/ClientID.hpp
+++ b/src/ClientID.hpp
@@ -61,14 +61,14 @@ private:
assert(_type == Type::jack);
}
- ClientID(const Type type, uint8_t alsa_id)
+ ClientID(const Type type, const uint8_t alsa_id)
: _type{type}
, _alsa_id{alsa_id}
{
assert(_type == Type::alsa);
}
- Type _type; ///< Type that determines which field is active
+ Type _type; ///< Determines which field is active
std::string _jack_name{}; ///< Client name for Type::jack
uint8_t _alsa_id{}; ///< Client ID for Type::alsa
};
diff --git a/src/JackDbusDriver.cpp b/src/JackDbusDriver.cpp
index 2ec3dd1..7d3a532 100644
--- a/src/JackDbusDriver.cpp
+++ b/src/JackDbusDriver.cpp
@@ -54,6 +54,16 @@ PATCHAGE_RESTORE_WARNINGS
//#define USE_FULL_REFRESH
+namespace {
+
+std::string
+full_name(const std::string& client_name, const std::string& port_name)
+{
+ return client_name + ":" + port_name;
+}
+
+} // namespace
+
JackDriver::JackDriver(Patchage* app, ILog& log)
: _app(app)
, _log(log)
@@ -600,7 +610,7 @@ JackDriver::add_port(PatchageModule* module,
new PatchagePort(*module,
type,
- id,
+ std::move(id),
name,
"", // TODO: pretty name
is_input,
@@ -611,7 +621,7 @@ JackDriver::add_port(PatchageModule* module,
void
JackDriver::add_port(dbus_uint64_t /*client_id*/,
const char* client_name,
- dbus_uint64_t port_id,
+ dbus_uint64_t /*port_id*/,
const char* port_name,
dbus_uint32_t port_flags,
dbus_uint32_t port_type)
@@ -644,7 +654,7 @@ JackDriver::add_port(dbus_uint64_t /*client_id*/,
add_port(module,
local_port_type,
- PortID{static_cast<jack_port_id_t>(port_id), false},
+ PortID::jack(full_name(client_name, port_name)),
port_name,
port_flags & JACKDBUS_PORT_FLAG_INPUT);
}
diff --git a/src/JackDriver.cpp b/src/JackDriver.cpp
index e20613c..e0b01ff 100644
--- a/src/JackDriver.cpp
+++ b/src/JackDriver.cpp
@@ -138,12 +138,13 @@ JackDriver::destroy_all()
PatchagePort*
JackDriver::create_port_view(Patchage* patchage, const PortID& id)
{
- assert(id.type == PortID::Type::jack_id);
+ assert(id.type() == PortID::Type::jack);
- jack_port_t* jack_port = jack_port_by_id(_client, id.id.jack_id);
+ jack_port_t* const jack_port =
+ jack_port_by_name(_client, id.jack_name().c_str());
if (!jack_port) {
- _log.error(fmt::format("[JACK] Failed to find port with ID \"{}\"",
- id.id.jack_id));
+ _log.error(fmt::format("[JACK] Failed to find port with name \"{}\"",
+ id.jack_name()));
return nullptr;
}
@@ -261,7 +262,7 @@ JackDriver::create_port(PatchageModule& parent,
_app->show_human_names(),
order);
- if (id.type != PortID::Type::nothing) {
+ if (id.type() != PortID::Type::nothing) {
dynamic_cast<PatchageCanvas*>(parent.canvas())->index_port(id, ret);
}
@@ -280,8 +281,7 @@ JackDriver::shutdown()
void
JackDriver::refresh()
{
- const char** ports = nullptr;
- jack_port_t* port = nullptr;
+ jack_port_t* port = nullptr;
// Jack can take _client away from us at any time throughout here :/
// Shortest locks possible is the best solution I can figure out
@@ -293,8 +293,8 @@ JackDriver::refresh()
return;
}
- ports =
- jack_get_ports(_client, nullptr, nullptr, 0); // get all existing ports
+ // Get all existing ports
+ const char** ports = jack_get_ports(_client, nullptr, nullptr, 0);
if (!ports) {
return;
@@ -333,7 +333,7 @@ JackDriver::refresh()
}
if (!m->get_port(jack_port_short_name(port))) {
- create_port(*m, port, PortID());
+ create_port(*m, port, PortID::jack(ports[i]));
}
}
@@ -407,8 +407,8 @@ JackDriver::port_names(const PortID& id,
{
jack_port_t* jack_port = nullptr;
- if (id.type == PortID::Type::jack_id) {
- jack_port = jack_port_by_id(_client, id.id.jack_id);
+ if (id.type() == PortID::Type::jack) {
+ jack_port = jack_port_by_name(_client, id.jack_name().c_str());
}
if (!jack_port) {
@@ -522,12 +522,15 @@ JackDriver::jack_port_registration_cb(jack_port_id_t port_id,
auto* me = static_cast<JackDriver*>(jack_driver);
assert(me->_client);
+ jack_port_t* const port = jack_port_by_id(me->_client, port_id);
+ const char* const name = jack_port_name(port);
+
if (registered) {
- me->_events.push(
- PatchageEvent(PatchageEvent::Type::port_creation, port_id));
+ me->_events.push(PatchageEvent(PatchageEvent::Type::port_creation,
+ PortID::jack(name)));
} else {
- me->_events.push(
- PatchageEvent(PatchageEvent::Type::port_destruction, port_id));
+ me->_events.push(PatchageEvent(PatchageEvent::Type::port_destruction,
+ PortID::jack(name)));
}
}
@@ -540,12 +543,19 @@ JackDriver::jack_port_connect_cb(jack_port_id_t src,
auto* me = static_cast<JackDriver*>(jack_driver);
assert(me->_client);
+ jack_port_t* const src_port = jack_port_by_id(me->_client, src);
+ jack_port_t* const dst_port = jack_port_by_id(me->_client, dst);
+ const char* const src_name = jack_port_name(src_port);
+ const char* const dst_name = jack_port_name(dst_port);
+
if (connect) {
- me->_events.push(
- PatchageEvent(PatchageEvent::Type::connection, src, dst));
+ me->_events.push(PatchageEvent(PatchageEvent::Type::connection,
+ PortID::jack(src_name),
+ PortID::jack(dst_name)));
} else {
- me->_events.push(
- PatchageEvent(PatchageEvent::Type::disconnection, src, dst));
+ me->_events.push(PatchageEvent(PatchageEvent::Type::disconnection,
+ PortID::jack(src_name),
+ PortID::jack(dst_name)));
}
}
diff --git a/src/PatchageCanvas.cpp b/src/PatchageCanvas.cpp
index 16a85ef..1433244 100644
--- a/src/PatchageCanvas.cpp
+++ b/src/PatchageCanvas.cpp
@@ -85,44 +85,13 @@ PatchageCanvas::remove_module(const std::string& name)
PatchagePort*
PatchageCanvas::find_port(const PortID& id)
{
- PatchagePort* pp = nullptr;
-
auto i = _port_index.find(id);
if (i != _port_index.end()) {
assert(i->second->get_module());
return i->second;
}
-#ifdef PATCHAGE_LIBJACK
- // Alsa ports are always indexed (or don't exist at all)
- if (id.type == PortID::Type::jack_id) {
- jack_port_t* jack_port =
- jack_port_by_id(_app->jack_driver()->client(), id.id.jack_id);
- if (!jack_port) {
- return nullptr;
- }
-
- std::string module_name;
- std::string port_name;
- _app->jack_driver()->port_names(id, module_name, port_name);
-
- PatchageModule* module =
- find_module(module_name,
- (jack_port_flags(jack_port) & JackPortIsInput)
- ? ModuleType::input
- : ModuleType::output);
-
- if (module) {
- pp = module->get_port(port_name);
- }
-
- if (pp) {
- index_port(id, pp);
- }
- }
-#endif // PATCHAGE_LIBJACK
-
- return pp;
+ return nullptr;
}
void
diff --git a/src/PatchageEvent.cpp b/src/PatchageEvent.cpp
index ce9cd48..abff4b8 100644
--- a/src/PatchageEvent.cpp
+++ b/src/PatchageEvent.cpp
@@ -56,12 +56,12 @@ PatchageEvent::execute(Patchage* patchage)
} else if (_type == Type::port_creation) {
Driver* driver = nullptr;
- if (_port_1.type == PortID::Type::jack_id) {
+ if (_port_1.type() == PortID::Type::jack) {
#if defined(PATCHAGE_LIBJACK) || defined(HAVE_JACK_DBUS)
driver = patchage->jack_driver();
#endif
#ifdef HAVE_ALSA
- } else if (_port_1.type == PortID::Type::alsa_addr) {
+ } else if (_port_1.type() == PortID::Type::alsa) {
driver = patchage->alsa_driver();
#endif
}
diff --git a/src/PatchageEvent.hpp b/src/PatchageEvent.hpp
index 2bb239a..dca4dbd 100644
--- a/src/PatchageEvent.hpp
+++ b/src/PatchageEvent.hpp
@@ -22,19 +22,11 @@
#include "PatchagePort.hpp"
#include "PortID.hpp"
-#ifdef PATCHAGE_LIBJACK
-# include <jack/jack.h>
-#endif
-#ifdef HAVE_ALSA
-# include <alsa/asoundlib.h>
-#endif
-
#include <cstring>
class Patchage;
-/** A Driver event to be processed by the GUI thread.
- */
+/// An event from drivers that is processed by the GUI
class PatchageEvent
{
public:
@@ -50,25 +42,22 @@ public:
disconnection,
};
- explicit PatchageEvent(Type type = Type::noop)
- : _type(type)
- {}
-
PatchageEvent(Type type, const char* str)
: _str(g_strdup(str))
+ , _port_1(PortID::nothing())
+ , _port_2(PortID::nothing())
, _type(type)
{}
- template<typename P>
- PatchageEvent(Type type, P port)
- : _port_1(port)
+ PatchageEvent(Type type, PortID port)
+ : _port_1(std::move(port))
+ , _port_2(PortID::nothing())
, _type(type)
{}
- template<typename P>
- PatchageEvent(Type type, P port_1, P port_2)
- : _port_1(port_1, false)
- , _port_2(port_2, true)
+ PatchageEvent(Type type, PortID tail, PortID head)
+ : _port_1(std::move(tail))
+ , _port_2(std::move(head))
, _type(type)
{}
diff --git a/src/PatchagePort.hpp b/src/PatchagePort.hpp
index 03a6f83..32b0cec 100644
--- a/src/PatchagePort.hpp
+++ b/src/PatchagePort.hpp
@@ -54,7 +54,7 @@ public:
is_input,
color)
, _type(type)
- , _id(id)
+ , _id(std::move(id))
, _name(name)
, _human_name(human_name)
, _order(order)
diff --git a/src/PortID.hpp b/src/PortID.hpp
index 2d41f92..2a53881 100644
--- a/src/PortID.hpp
+++ b/src/PortID.hpp
@@ -17,126 +17,117 @@
#ifndef PATCHAGE_PORTID_HPP
#define PATCHAGE_PORTID_HPP
-#include "patchage_config.h"
-
-#include "PatchagePort.hpp"
-
-#ifdef PATCHAGE_LIBJACK
-# include <jack/jack.h>
-#endif
-#ifdef HAVE_ALSA
-# include <alsa/asoundlib.h>
-#endif
-
-#include <cstring>
+#include <cassert>
#include <iostream>
+#include <string>
+#include <tuple>
+/// An ID for some port on a client (program)
struct PortID
{
enum class Type
{
nothing,
- jack_id,
- alsa_addr,
+ jack,
+ alsa,
};
- PortID() = default;
+ PortID(const PortID& copy) = default;
+ PortID& operator=(const PortID& copy) = default;
-#if defined(PATCHAGE_LIBJACK) || defined(HAVE_JACK_DBUS)
- explicit PortID(uint32_t jack_id, bool = false)
- : type(Type::jack_id)
+ PortID(PortID&& id) = default;
+ PortID& operator=(PortID&& id) = default;
+
+ ~PortID() = default;
+
+ /// Return a null ID that refers to nothing
+ static PortID nothing() { return PortID{}; }
+
+ /// Return an ID for a JACK port by full name (like "client:port")
+ static PortID jack(std::string name)
{
- id.jack_id = jack_id;
+ return PortID{Type::jack, std::move(name)};
}
-#endif
-#ifdef HAVE_ALSA
- PortID(snd_seq_addr_t addr, bool in)
- : type(Type::alsa_addr)
+ /// Return an ID for an ALSA Sequencer port by ID
+ static PortID
+ alsa(const uint8_t client_id, const uint8_t port, const bool is_input)
{
- id.alsa_addr = addr;
- id.is_input = in;
+ return PortID{Type::alsa, client_id, port, is_input};
}
-#endif
- PortID(const PortID& copy) = default;
- PortID& operator=(const PortID& copy) = default;
-
- PortID(PortID&& id) = default;
- PortID& operator=(PortID&& id) = default;
+ Type type() const { return _type; }
+ const std::string& jack_name() const { return _jack_name; }
+ uint8_t alsa_client() const { return _alsa_client; }
+ uint8_t alsa_port() const { return _alsa_port; }
+ bool alsa_is_input() const { return _alsa_is_input; }
- ~PortID() = default;
+private:
+ PortID() = default;
- Type type = Type::nothing;
+ PortID(const Type type, std::string jack_name)
+ : _type{type}
+ , _jack_name{std::move(jack_name)}
+ {
+ assert(_type == Type::jack);
+ }
- union
+ PortID(const Type type,
+ const uint8_t alsa_client,
+ const uint8_t alsa_port,
+ const bool is_input)
+ : _type{type}
+ , _alsa_client{alsa_client}
+ , _alsa_port{alsa_port}
+ , _alsa_is_input{is_input}
{
-#if defined(PATCHAGE_LIBJACK) || defined(HAVE_JACK_DBUS)
- uint32_t jack_id;
-#endif
-#ifdef HAVE_ALSA
- struct
- {
- snd_seq_addr_t alsa_addr;
- bool is_input : 1;
- };
-#endif
- } id = {};
+ assert(_type == Type::alsa);
+ }
+
+ Type _type{Type::nothing}; ///< Determines which field is active
+ std::string _jack_name{}; ///< Full port name for Type::jack
+ uint8_t _alsa_client{}; ///< Client ID for Type::alsa
+ uint8_t _alsa_port{}; ///< Port ID for Type::alsa
+ bool _alsa_is_input{}; ///< Input flag for Type::alsa
};
static inline std::ostream&
operator<<(std::ostream& os, const PortID& id)
{
- switch (id.type) {
+ switch (id.type()) {
case PortID::Type::nothing:
return os << "(null)";
- case PortID::Type::jack_id:
-#ifdef PATCHAGE_LIBJACK
- return os << "jack:" << id.id.jack_id;
-#endif
- break;
- case PortID::Type::alsa_addr:
-#ifdef HAVE_ALSA
- return os << "alsa:" << int(id.id.alsa_addr.client) << ":"
- << int(id.id.alsa_addr.port) << ":"
- << (id.id.is_input ? "in" : "out");
-#endif
- break;
+ case PortID::Type::jack:
+ return os << "jack:" << id.jack_name();
+ case PortID::Type::alsa:
+ return os << "alsa:" << int(id.alsa_client()) << ":"
+ << int(id.alsa_port()) << ":"
+ << (id.alsa_is_input() ? "in" : "out");
}
+
assert(false);
return os;
}
static inline bool
-operator<(const PortID& a, const PortID& b)
+operator<(const PortID& lhs, const PortID& rhs)
{
- if (a.type != b.type) {
- return a.type < b.type;
+ if (lhs.type() != rhs.type()) {
+ return lhs.type() < rhs.type();
}
- switch (a.type) {
+ switch (lhs.type()) {
case PortID::Type::nothing:
return true;
- case PortID::Type::jack_id:
-#if defined(PATCHAGE_LIBJACK) || defined(HAVE_JACK_DBUS)
- return a.id.jack_id < b.id.jack_id;
-#endif
- break;
- case PortID::Type::alsa_addr:
-#ifdef HAVE_ALSA
- if ((a.id.alsa_addr.client < b.id.alsa_addr.client) ||
- ((a.id.alsa_addr.client == b.id.alsa_addr.client) &&
- a.id.alsa_addr.port < b.id.alsa_addr.port)) {
- return true;
- } else if (a.id.alsa_addr.client == b.id.alsa_addr.client &&
- a.id.alsa_addr.port == b.id.alsa_addr.port) {
- return (a.id.is_input < b.id.is_input);
- } else {
- return false;
- }
-#endif
- break;
+ case PortID::Type::jack:
+ return lhs.jack_name() < rhs.jack_name();
+ case PortID::Type::alsa:
+ return std::make_tuple(
+ lhs.alsa_client(), lhs.alsa_port(), lhs.alsa_is_input()) <
+ std::make_tuple(
+ rhs.alsa_client(), rhs.alsa_port(), rhs.alsa_is_input());
}
+
assert(false);
return false;
}