summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/AlsaDriver.cpp62
-rw-r--r--src/AlsaDriver.hpp79
-rw-r--r--src/JackDbusDriver.cpp83
-rw-r--r--src/JackDbusDriver.hpp102
-rw-r--r--src/JackDriver.hpp94
-rw-r--r--src/JackLibDriver.cpp (renamed from src/JackDriver.cpp)143
-rw-r--r--src/Patchage.cpp130
-rw-r--r--src/Patchage.hpp3
-rw-r--r--src/make_alsa_driver.hpp42
-rw-r--r--src/make_jack_driver.hpp42
10 files changed, 387 insertions, 393 deletions
diff --git a/src/AlsaDriver.cpp b/src/AlsaDriver.cpp
index 79c1491..bc80d48 100644
--- a/src/AlsaDriver.cpp
+++ b/src/AlsaDriver.cpp
@@ -14,11 +14,12 @@
* along with Patchage. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "AlsaDriver.hpp"
+#include "make_alsa_driver.hpp"
#include "ClientID.hpp"
#include "ClientInfo.hpp"
#include "ClientType.hpp"
+#include "Driver.hpp"
#include "ILog.hpp"
#include "PortInfo.hpp"
#include "PortType.hpp"
@@ -30,6 +31,9 @@ PATCHAGE_DISABLE_FMT_WARNINGS
#include <fmt/ostream.h>
PATCHAGE_RESTORE_WARNINGS
+#include <alsa/asoundlib.h>
+#include <pthread.h>
+
#include <cassert>
#include <limits>
#include <set>
@@ -38,6 +42,56 @@ PATCHAGE_RESTORE_WARNINGS
namespace {
+/// Driver for ALSA Sequencer ports
+class AlsaDriver : public Driver
+{
+public:
+ explicit AlsaDriver(ILog& log, EventSink emit_event);
+
+ AlsaDriver(const AlsaDriver&) = delete;
+ AlsaDriver& operator=(const AlsaDriver&) = delete;
+
+ AlsaDriver(AlsaDriver&&) = delete;
+ AlsaDriver& operator=(AlsaDriver&&) = delete;
+
+ ~AlsaDriver() override;
+
+ void attach(bool launch_daemon) override;
+ void detach() override;
+
+ bool is_attached() const override { return (_seq != nullptr); }
+
+ void refresh(const EventSink& sink) override;
+
+ bool connect(const PortID& tail_id, const PortID& head_id) override;
+
+ bool disconnect(const PortID& tail_id, const PortID& head_id) override;
+
+private:
+ bool create_refresh_port();
+ static void* refresh_main(void* me);
+ void _refresh_main();
+
+ ILog& _log;
+ snd_seq_t* _seq;
+ pthread_t _refresh_thread;
+
+ struct SeqAddrComparator
+ {
+ bool operator()(const snd_seq_addr_t& a, const snd_seq_addr_t& b) const
+ {
+ return ((a.client < b.client) ||
+ ((a.client == b.client) && a.port < b.port));
+ }
+ };
+
+ using Ignored = std::set<snd_seq_addr_t, SeqAddrComparator>;
+
+ Ignored _ignored;
+
+ bool ignore(const snd_seq_addr_t& addr, bool add = true);
+};
+
PortID
addr_to_id(const snd_seq_addr_t& addr, const bool is_input)
{
@@ -489,3 +543,9 @@ AlsaDriver::_refresh_main()
}
}
}
+
+std::unique_ptr<Driver>
+make_alsa_driver(ILog& log, Driver::EventSink emit_event)
+{
+ return std::unique_ptr<Driver>{new AlsaDriver{log, std::move(emit_event)}};
+}
diff --git a/src/AlsaDriver.hpp b/src/AlsaDriver.hpp
deleted file mode 100644
index 0dd2008..0000000
--- a/src/AlsaDriver.hpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/* This file is part of Patchage.
- * Copyright 2007-2020 David Robillard <d@drobilla.net>
- *
- * Patchage is free software: you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef PATCHAGE_ALSADRIVER_HPP
-#define PATCHAGE_ALSADRIVER_HPP
-
-#include "Driver.hpp"
-
-#include <alsa/asoundlib.h>
-#include <pthread.h>
-
-#include <set>
-
-class ILog;
-
-/// Driver for ALSA Sequencer ports
-class AlsaDriver : public Driver
-{
-public:
- explicit AlsaDriver(ILog& log, EventSink emit_event);
-
- AlsaDriver(const AlsaDriver&) = delete;
- AlsaDriver& operator=(const AlsaDriver&) = delete;
-
- AlsaDriver(AlsaDriver&&) = delete;
- AlsaDriver& operator=(AlsaDriver&&) = delete;
-
- ~AlsaDriver() override;
-
- void attach(bool launch_daemon) override;
- void detach() override;
-
- bool is_attached() const override { return (_seq != nullptr); }
-
- void refresh(const EventSink& sink) override;
-
- bool connect(const PortID& tail_id, const PortID& head_id) override;
-
- bool disconnect(const PortID& tail_id, const PortID& head_id) override;
-
-private:
- bool create_refresh_port();
- static void* refresh_main(void* me);
- void _refresh_main();
-
- ILog& _log;
- snd_seq_t* _seq;
- pthread_t _refresh_thread;
-
- struct SeqAddrComparator
- {
- bool operator()(const snd_seq_addr_t& a, const snd_seq_addr_t& b) const
- {
- return ((a.client < b.client) ||
- ((a.client == b.client) && a.port < b.port));
- }
- };
-
- using Ignored = std::set<snd_seq_addr_t, SeqAddrComparator>;
-
- Ignored _ignored;
-
- bool ignore(const snd_seq_addr_t& addr, bool add = true);
-};
-
-#endif // PATCHAGE_ALSADRIVER_HPP
diff --git a/src/JackDbusDriver.cpp b/src/JackDbusDriver.cpp
index add838d..c656594 100644
--- a/src/JackDbusDriver.cpp
+++ b/src/JackDbusDriver.cpp
@@ -15,8 +15,6 @@
* along with Patchage. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "JackDbusDriver.hpp"
-
#include "ClientType.hpp"
#include "Driver.hpp"
#include "ILog.hpp"
@@ -24,6 +22,7 @@
#include "PortNames.hpp"
#include "PortType.hpp"
#include "SignalDirection.hpp"
+#include "make_jack_driver.hpp"
#include "warnings.hpp"
PATCHAGE_DISABLE_FMT_WARNINGS
@@ -37,6 +36,7 @@ PATCHAGE_RESTORE_WARNINGS
#include <glib.h>
#include <cassert>
+#include <cstdint>
#include <cstring>
#include <set>
#include <string>
@@ -54,6 +54,78 @@ PATCHAGE_RESTORE_WARNINGS
#define JACKDBUS_PORT_TYPE_AUDIO 0
#define JACKDBUS_PORT_TYPE_MIDI 1
+/// Driver for JACK audio and midi ports that uses D-Bus
+class JackDriver : public AudioDriver
+{
+public:
+ explicit JackDriver(ILog& log, EventSink emit_event);
+
+ JackDriver(const JackDriver&) = delete;
+ JackDriver& operator=(const JackDriver&) = delete;
+
+ JackDriver(JackDriver&&) = delete;
+ JackDriver& operator=(JackDriver&&) = delete;
+
+ ~JackDriver() override;
+
+ // Driver interface
+ void attach(bool launch_daemon) override;
+ void detach() override;
+ bool is_attached() const override;
+ void refresh(const EventSink& sink) override;
+ bool connect(const PortID& tail_id, const PortID& head_id) override;
+ bool disconnect(const PortID& tail_id, const PortID& head_id) override;
+
+ // AudioDriver interface
+ uint32_t xruns() override;
+ void reset_xruns() override;
+ uint32_t buffer_size() override;
+ bool set_buffer_size(uint32_t frames) override;
+ uint32_t sample_rate() override;
+
+private:
+ PortType patchage_port_type(dbus_uint32_t dbus_port_type) const;
+
+ PortInfo port_info(const std::string& port_name,
+ dbus_uint32_t port_type,
+ dbus_uint32_t port_flags) const;
+
+ void error_msg(const std::string& msg) const;
+ void info_msg(const std::string& msg) const;
+
+ bool call(bool response_expected,
+ const char* iface,
+ const char* method,
+ DBusMessage** reply_ptr_ptr,
+ int in_type,
+ ...);
+
+ void update_attached();
+
+ bool is_started();
+
+ void start_server();
+
+ void stop_server();
+
+ static DBusHandlerResult dbus_message_hook(DBusConnection* connection,
+ DBusMessage* message,
+ void* jack_driver);
+
+ void on_jack_appeared();
+
+ void on_jack_disappeared();
+
+ ILog& _log;
+ DBusError _dbus_error;
+ DBusConnection* _dbus_connection;
+
+ mutable bool _server_responding;
+ bool _server_started;
+
+ dbus_uint64_t _graph_version;
+};
+
JackDriver::JackDriver(ILog& log, EventSink emit_event)
: AudioDriver{std::move(emit_event)}
, _log(log)
@@ -900,3 +972,10 @@ JackDriver::info_msg(const std::string& msg) const
{
_log.info(std::string{"[JACK] "} + msg);
}
+
+std::unique_ptr<AudioDriver>
+make_jack_driver(ILog& log, Driver::EventSink emit_event)
+{
+ return std::unique_ptr<AudioDriver>{
+ new JackDriver{log, std::move(emit_event)}};
+}
diff --git a/src/JackDbusDriver.hpp b/src/JackDbusDriver.hpp
deleted file mode 100644
index 068c7cc..0000000
--- a/src/JackDbusDriver.hpp
+++ /dev/null
@@ -1,102 +0,0 @@
-/* This file is part of Patchage.
- * Copyright 2008-2020 David Robillard <d@drobilla.net>
- * Copyright 2008 Nedko Arnaudov <nedko@arnaudov.name>
- *
- * Patchage is free software: you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef PATCHAGE_JACKDBUSDRIVER_HPP
-#define PATCHAGE_JACKDBUSDRIVER_HPP
-
-#include "AudioDriver.hpp"
-
-#include <dbus/dbus.h>
-
-#include <cstdint>
-#include <string>
-
-class ILog;
-
-/// Driver for JACK audio and midi ports that uses D-Bus
-class JackDriver : public AudioDriver
-{
-public:
- explicit JackDriver(ILog& log, EventSink emit_event);
-
- JackDriver(const JackDriver&) = delete;
- JackDriver& operator=(const JackDriver&) = delete;
-
- JackDriver(JackDriver&&) = delete;
- JackDriver& operator=(JackDriver&&) = delete;
-
- ~JackDriver() override;
-
- // Driver interface
- void attach(bool launch_daemon) override;
- void detach() override;
- bool is_attached() const override;
- void refresh(const EventSink& sink) override;
- bool connect(const PortID& tail_id, const PortID& head_id) override;
- bool disconnect(const PortID& tail_id, const PortID& head_id) override;
-
- // AudioDriver interface
- uint32_t xruns() override;
- void reset_xruns() override;
- uint32_t buffer_size() override;
- bool set_buffer_size(uint32_t frames) override;
- uint32_t sample_rate() override;
-
-private:
- PortType patchage_port_type(dbus_uint32_t dbus_port_type) const;
-
- PortInfo port_info(const std::string& port_name,
- dbus_uint32_t port_type,
- dbus_uint32_t port_flags) const;
-
- void error_msg(const std::string& msg) const;
- void info_msg(const std::string& msg) const;
-
- bool call(bool response_expected,
- const char* iface,
- const char* method,
- DBusMessage** reply_ptr_ptr,
- int in_type,
- ...);
-
- void update_attached();
-
- bool is_started();
-
- void start_server();
-
- void stop_server();
-
- static DBusHandlerResult dbus_message_hook(DBusConnection* connection,
- DBusMessage* message,
- void* jack_driver);
-
- void on_jack_appeared();
-
- void on_jack_disappeared();
-
- ILog& _log;
- DBusError _dbus_error;
- DBusConnection* _dbus_connection;
-
- mutable bool _server_responding;
- bool _server_started;
-
- dbus_uint64_t _graph_version;
-};
-
-#endif // PATCHAGE_JACKDBUSDRIVER_HPP
diff --git a/src/JackDriver.hpp b/src/JackDriver.hpp
deleted file mode 100644
index 078e7d2..0000000
--- a/src/JackDriver.hpp
+++ /dev/null
@@ -1,94 +0,0 @@
-/* This file is part of Patchage.
- * Copyright 2007-2020 David Robillard <d@drobilla.net>
- *
- * Patchage is free software: you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef PATCHAGE_JACKDRIVER_HPP
-#define PATCHAGE_JACKDRIVER_HPP
-
-#include "AudioDriver.hpp"
-#include "ClientInfo.hpp"
-#include "PortInfo.hpp"
-
-#include <jack/jack.h>
-
-#include <cstdint>
-#include <mutex>
-#include <string>
-
-class ILog;
-
-/// Driver for JACK audio and midi ports that uses libjack
-class JackDriver : public AudioDriver
-{
-public:
- explicit JackDriver(ILog& log, EventSink emit_event);
-
- JackDriver(const JackDriver&) = delete;
- JackDriver& operator=(const JackDriver&) = delete;
-
- JackDriver(JackDriver&&) = delete;
- JackDriver& operator=(JackDriver&&) = delete;
-
- ~JackDriver() override;
-
- // Driver interface
- void attach(bool launch_daemon) override;
- void detach() override;
- bool is_attached() const override;
- void refresh(const EventSink& sink) override;
- bool connect(const PortID& tail_id, const PortID& head_id) override;
- bool disconnect(const PortID& tail_id, const PortID& head_id) override;
-
- // AudioDriver interface
- uint32_t xruns() override;
- void reset_xruns() override;
- uint32_t buffer_size() override;
- bool set_buffer_size(uint32_t frames) override;
- uint32_t sample_rate() override;
-
-private:
- ClientInfo get_client_info(const char* name);
- PortInfo get_port_info(const jack_port_t* port);
-
- void shutdown();
-
- static void jack_client_registration_cb(const char* name,
- int registered,
- void* jack_driver);
-
- static void jack_port_registration_cb(jack_port_id_t port_id,
- int registered,
- void* jack_driver);
-
- static void jack_port_connect_cb(jack_port_id_t src,
- jack_port_id_t dst,
- int connect,
- void* jack_driver);
-
- static int jack_xrun_cb(void* jack_driver);
-
- static void jack_shutdown_cb(void* jack_driver);
-
- ILog& _log;
- std::mutex _shutdown_mutex;
-
- jack_client_t* _client = nullptr;
- jack_nframes_t _buffer_size = 0u;
- uint32_t _xruns = 0u;
-
- bool _is_activated : 1;
-};
-
-#endif // PATCHAGE_JACKDRIVER_HPP
diff --git a/src/JackDriver.cpp b/src/JackLibDriver.cpp
index b3c7658..86c1609 100644
--- a/src/JackDriver.cpp
+++ b/src/JackLibDriver.cpp
@@ -14,16 +14,18 @@
* along with Patchage. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "JackDriver.hpp"
-
+#include "AudioDriver.hpp"
#include "ClientID.hpp"
+#include "ClientInfo.hpp"
#include "ClientType.hpp"
#include "ILog.hpp"
#include "PatchageEvent.hpp"
+#include "PortInfo.hpp"
#include "PortNames.hpp"
#include "PortType.hpp"
#include "SignalDirection.hpp"
#include "jackey.h"
+#include "make_jack_driver.hpp"
#include "patchage_config.h"
#include "warnings.hpp"
@@ -39,25 +41,89 @@ PATCHAGE_RESTORE_WARNINGS
#include <jack/statistics.h>
#include <cassert>
+#include <cstdint>
#include <cstring>
+#include <mutex>
#include <set>
#include <string>
#include <unordered_set>
#include <utility>
-JackDriver::JackDriver(ILog& log, EventSink emit_event)
+/// Driver for JACK audio and midi ports that uses libjack
+class JackLibDriver : public AudioDriver
+{
+public:
+ explicit JackLibDriver(ILog& log, EventSink emit_event);
+
+ JackLibDriver(const JackLibDriver&) = delete;
+ JackLibDriver& operator=(const JackLibDriver&) = delete;
+
+ JackLibDriver(JackLibDriver&&) = delete;
+ JackLibDriver& operator=(JackLibDriver&&) = delete;
+
+ ~JackLibDriver() override;
+
+ // Driver interface
+ void attach(bool launch_daemon) override;
+ void detach() override;
+ bool is_attached() const override;
+ void refresh(const EventSink& sink) override;
+ bool connect(const PortID& tail_id, const PortID& head_id) override;
+ bool disconnect(const PortID& tail_id, const PortID& head_id) override;
+
+ // AudioDriver interface
+ uint32_t xruns() override;
+ void reset_xruns() override;
+ uint32_t buffer_size() override;
+ bool set_buffer_size(uint32_t frames) override;
+ uint32_t sample_rate() override;
+
+private:
+ ClientInfo get_client_info(const char* name);
+ PortInfo get_port_info(const jack_port_t* port);
+
+ void shutdown();
+
+ static void jack_client_registration_cb(const char* name,
+ int registered,
+ void* jack_driver);
+
+ static void jack_port_registration_cb(jack_port_id_t port_id,
+ int registered,
+ void* jack_driver);
+
+ static void jack_port_connect_cb(jack_port_id_t src,
+ jack_port_id_t dst,
+ int connect,
+ void* jack_driver);
+
+ static int jack_xrun_cb(void* jack_driver);
+
+ static void jack_shutdown_cb(void* jack_driver);
+
+ ILog& _log;
+ std::mutex _shutdown_mutex;
+
+ jack_client_t* _client = nullptr;
+ jack_nframes_t _buffer_size = 0u;
+ uint32_t _xruns = 0u;
+
+ bool _is_activated : 1;
+};
+
+JackLibDriver::JackLibDriver(ILog& log, EventSink emit_event)
: AudioDriver{std::move(emit_event)}
, _log{log}
, _is_activated{false}
{}
-JackDriver::~JackDriver()
+JackLibDriver::~JackLibDriver()
{
detach();
}
void
-JackDriver::attach(const bool launch_daemon)
+JackLibDriver::attach(const bool launch_daemon)
{
if (_client) {
return; // Already connected
@@ -94,7 +160,7 @@ JackDriver::attach(const bool launch_daemon)
}
void
-JackDriver::detach()
+JackLibDriver::detach()
{
std::lock_guard<std::mutex> lock{_shutdown_mutex};
@@ -109,7 +175,7 @@ JackDriver::detach()
}
bool
-JackDriver::is_attached() const
+JackLibDriver::is_attached() const
{
return _client != nullptr;
}
@@ -136,13 +202,13 @@ get_property(const jack_uuid_t subject, const char* const key)
}
ClientInfo
-JackDriver::get_client_info(const char* const name)
+JackLibDriver::get_client_info(const char* const name)
{
return {name}; // TODO: Pretty name?
}
PortInfo
-JackDriver::get_port_info(const jack_port_t* const port)
+JackLibDriver::get_port_info(const jack_port_t* const port)
{
const auto uuid = jack_port_uuid(port);
const auto flags = jack_port_flags(port);
@@ -190,13 +256,13 @@ JackDriver::get_port_info(const jack_port_t* const port)
}
void
-JackDriver::shutdown()
+JackLibDriver::shutdown()
{
_emit_event(DriverDetachmentEvent{ClientType::jack});
}
void
-JackDriver::refresh(const EventSink& sink)
+JackLibDriver::refresh(const EventSink& sink)
{
std::lock_guard<std::mutex> lock{_shutdown_mutex};
@@ -261,7 +327,7 @@ JackDriver::refresh(const EventSink& sink)
}
bool
-JackDriver::connect(const PortID& tail_id, const PortID& head_id)
+JackLibDriver::connect(const PortID& tail_id, const PortID& head_id)
{
if (!_client) {
return false;
@@ -284,7 +350,7 @@ JackDriver::connect(const PortID& tail_id, const PortID& head_id)
}
bool
-JackDriver::disconnect(const PortID& tail_id, const PortID& head_id)
+JackLibDriver::disconnect(const PortID& tail_id, const PortID& head_id)
{
if (!_client) {
return false;
@@ -306,25 +372,25 @@ JackDriver::disconnect(const PortID& tail_id, const PortID& head_id)
}
uint32_t
-JackDriver::xruns()
+JackLibDriver::xruns()
{
return _xruns;
}
void
-JackDriver::reset_xruns()
+JackLibDriver::reset_xruns()
{
_xruns = 0;
}
uint32_t
-JackDriver::buffer_size()
+JackLibDriver::buffer_size()
{
return _is_activated ? _buffer_size : jack_get_buffer_size(_client);
}
bool
-JackDriver::set_buffer_size(const uint32_t frames)
+JackLibDriver::set_buffer_size(const uint32_t frames)
{
if (!_client) {
_buffer_size = frames;
@@ -345,17 +411,17 @@ JackDriver::set_buffer_size(const uint32_t frames)
}
uint32_t
-JackDriver::sample_rate()
+JackLibDriver::sample_rate()
{
return jack_get_sample_rate(_client);
}
void
-JackDriver::jack_client_registration_cb(const char* const name,
- const int registered,
- void* const jack_driver)
+JackLibDriver::jack_client_registration_cb(const char* const name,
+ const int registered,
+ void* const jack_driver)
{
- auto* const me = static_cast<JackDriver*>(jack_driver);
+ auto* const me = static_cast<JackLibDriver*>(jack_driver);
if (registered) {
me->_emit_event(ClientCreationEvent{ClientID::jack(name), {name}});
@@ -365,11 +431,11 @@ JackDriver::jack_client_registration_cb(const char* const name,
}
void
-JackDriver::jack_port_registration_cb(const jack_port_id_t port_id,
- const int registered,
- void* const jack_driver)
+JackLibDriver::jack_port_registration_cb(const jack_port_id_t port_id,
+ const int registered,
+ void* const jack_driver)
{
- auto* const me = static_cast<JackDriver*>(jack_driver);
+ auto* const me = static_cast<JackLibDriver*>(jack_driver);
jack_port_t* const port = jack_port_by_id(me->_client, port_id);
const char* const name = jack_port_name(port);
@@ -383,12 +449,12 @@ JackDriver::jack_port_registration_cb(const jack_port_id_t port_id,
}
void
-JackDriver::jack_port_connect_cb(const jack_port_id_t src,
- const jack_port_id_t dst,
- const int connect,
- void* const jack_driver)
+JackLibDriver::jack_port_connect_cb(const jack_port_id_t src,
+ const jack_port_id_t dst,
+ const int connect,
+ void* const jack_driver)
{
- auto* const me = static_cast<JackDriver*>(jack_driver);
+ auto* const me = static_cast<JackLibDriver*>(jack_driver);
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);
@@ -405,9 +471,9 @@ JackDriver::jack_port_connect_cb(const jack_port_id_t src,
}
int
-JackDriver::jack_xrun_cb(void* const jack_driver)
+JackLibDriver::jack_xrun_cb(void* const jack_driver)
{
- auto* const me = static_cast<JackDriver*>(jack_driver);
+ auto* const me = static_cast<JackLibDriver*>(jack_driver);
++me->_xruns;
@@ -415,9 +481,9 @@ JackDriver::jack_xrun_cb(void* const jack_driver)
}
void
-JackDriver::jack_shutdown_cb(void* const jack_driver)
+JackLibDriver::jack_shutdown_cb(void* const jack_driver)
{
- auto* const me = static_cast<JackDriver*>(jack_driver);
+ auto* const me = static_cast<JackLibDriver*>(jack_driver);
std::lock_guard<std::mutex> lock{me->_shutdown_mutex};
@@ -426,3 +492,10 @@ JackDriver::jack_shutdown_cb(void* const jack_driver)
me->_emit_event(DriverDetachmentEvent{ClientType::jack});
}
+
+std::unique_ptr<AudioDriver>
+make_jack_driver(ILog& log, Driver::EventSink emit_event)
+{
+ return std::unique_ptr<AudioDriver>{
+ new JackLibDriver{log, std::move(emit_event)}};
+}
diff --git a/src/Patchage.cpp b/src/Patchage.cpp
index 4f522f7..1e057bd 100644
--- a/src/Patchage.cpp
+++ b/src/Patchage.cpp
@@ -24,20 +24,11 @@
#include "UIFile.hpp"
#include "event_to_string.hpp"
#include "handle_event.hpp"
+#include "make_alsa_driver.hpp"
+#include "make_jack_driver.hpp"
#include "patchage_config.h"
#include "warnings.hpp"
-#if defined(HAVE_JACK_DBUS)
-# include "JackDbusDriver.hpp"
-#elif defined(PATCHAGE_LIBJACK)
-# include "JackDriver.hpp"
-# include <jack/statistics.h>
-#endif
-
-#ifdef HAVE_ALSA
-# include "AlsaDriver.hpp"
-#endif
-
PATCHAGE_DISABLE_GANV_WARNINGS
#include "ganv/Edge.hpp"
#include "ganv/Module.hpp"
@@ -202,16 +193,6 @@ Patchage::Patchage(Options options)
_status_text->signal_size_allocate().connect(
sigc::mem_fun(this, &Patchage::on_messages_resized));
-#ifdef HAVE_ALSA
- _menu_alsa_connect->signal_activate().connect(
- sigc::mem_fun(this, &Patchage::menu_alsa_connect));
- _menu_alsa_disconnect->signal_activate().connect(
- sigc::mem_fun(this, &Patchage::menu_alsa_disconnect));
-#else
- _menu_alsa_connect->set_sensitive(false);
- _menu_alsa_disconnect->set_sensitive(false);
-#endif
-
_menu_file_quit->signal_activate().connect(
sigc::mem_fun(this, &Patchage::on_quit));
_menu_export_image->signal_activate().connect(
@@ -288,24 +269,38 @@ Patchage::Patchage(Options options)
}
#endif
-#if defined(PATCHAGE_LIBJACK) || defined(HAVE_JACK_DBUS)
- _jack_driver = std::unique_ptr<AudioDriver>{new JackDriver(
- _log, [this](const PatchageEvent& event) { on_driver_event(event); })};
+ // Make Jack driver if possible
+ _jack_driver = make_jack_driver(
+ _log, [this](const PatchageEvent& event) { on_driver_event(event); });
- _connector.add_driver(PortID::Type::jack, _jack_driver.get());
+ if (_jack_driver) {
+ _connector.add_driver(PortID::Type::jack, _jack_driver.get());
- _menu_jack_connect->signal_activate().connect(sigc::bind(
- sigc::mem_fun(_jack_driver.get(), &AudioDriver::attach), true));
- _menu_jack_disconnect->signal_activate().connect(
- sigc::mem_fun(_jack_driver.get(), &AudioDriver::detach));
-#endif
+ _menu_jack_connect->signal_activate().connect(sigc::bind(
+ sigc::mem_fun(_jack_driver.get(), &AudioDriver::attach), true));
+ _menu_jack_disconnect->signal_activate().connect(
+ sigc::mem_fun(_jack_driver.get(), &AudioDriver::detach));
+ } else {
+ _menu_jack_connect->set_sensitive(false);
+ _menu_jack_disconnect->set_sensitive(false);
+ }
-#ifdef HAVE_ALSA
- _alsa_driver = std::unique_ptr<Driver>{new AlsaDriver(
- _log, [this](const PatchageEvent& event) { on_driver_event(event); })};
+ // Make ALSA driver if possible
+ _alsa_driver = make_alsa_driver(
+ _log, [this](const PatchageEvent& event) { on_driver_event(event); });
- _connector.add_driver(PortID::Type::alsa, _alsa_driver.get());
-#endif
+ if (_alsa_driver) {
+ _connector.add_driver(PortID::Type::alsa, _alsa_driver.get());
+
+ _menu_alsa_connect->signal_activate().connect(sigc::bind(
+ sigc::mem_fun(_alsa_driver.get(), &Driver::attach), false));
+ _menu_alsa_disconnect->signal_activate().connect(
+ sigc::mem_fun(_alsa_driver.get(), &Driver::detach));
+
+ } else {
+ _menu_alsa_connect->set_sensitive(false);
+ _menu_alsa_disconnect->set_sensitive(false);
+ }
update_state();
_menu_view_toolbar->set_active(_conf.get_show_toolbar());
@@ -397,8 +392,7 @@ Patchage::update_toolbar()
updating = true;
-#if defined(PATCHAGE_LIBJACK) || defined(HAVE_JACK_DBUS)
- if (_jack_driver->is_attached()) {
+ if (_jack_driver && _jack_driver->is_attached()) {
const auto buffer_size = _jack_driver->buffer_size();
const auto sample_rate = _jack_driver->sample_rate();
if (sample_rate != 0) {
@@ -415,7 +409,7 @@ Patchage::update_toolbar()
return;
}
}
-#endif
+
_latency_label->set_visible(false);
updating = false;
}
@@ -423,8 +417,7 @@ Patchage::update_toolbar()
bool
Patchage::update_load()
{
-#if defined(PATCHAGE_LIBJACK) || defined(HAVE_JACK_DBUS)
- if (_jack_driver->is_attached()) {
+ if (_jack_driver && _jack_driver->is_attached()) {
const auto xruns = _jack_driver->xruns();
if (xruns > 0u) {
_dropouts_label->set_text(fmt::format(" Dropouts: {}", xruns));
@@ -436,7 +429,6 @@ Patchage::update_load()
_clear_load_but->hide();
}
}
-#endif
return true;
}
@@ -459,11 +451,9 @@ Patchage::refresh()
if (_canvas) {
_canvas->clear();
-#if defined(PATCHAGE_LIBJACK) || defined(HAVE_JACK_DBUS)
if (_jack_driver) {
_jack_driver->refresh(sink);
}
-#endif
if (_alsa_driver) {
_alsa_driver->refresh(sink);
@@ -549,12 +539,12 @@ Patchage::store_window_location()
void
Patchage::clear_load()
{
-#if defined(PATCHAGE_LIBJACK) || defined(HAVE_JACK_DBUS)
_dropouts_label->set_text(" Dropouts: 0");
_dropouts_label->hide();
_clear_load_but->hide();
- _jack_driver->reset_xruns();
-#endif
+ if (_jack_driver) {
+ _jack_driver->reset_xruns();
+ }
}
static void
@@ -596,22 +586,6 @@ Patchage::process_events()
}
void
-Patchage::menu_alsa_connect()
-{
- if (_alsa_driver) {
- _alsa_driver->attach(false);
- }
-}
-
-void
-Patchage::menu_alsa_disconnect()
-{
- if (_alsa_driver) {
- _alsa_driver->detach();
- }
-}
-
-void
Patchage::on_arrange()
{
if (_canvas) {
@@ -795,12 +769,14 @@ Patchage::save()
void
Patchage::on_quit()
{
-#ifdef HAVE_ALSA
- _alsa_driver->detach();
-#endif
-#if defined(PATCHAGE_LIBJACK) || defined(HAVE_JACK_DBUS)
- _jack_driver->detach();
-#endif
+ if (_alsa_driver) {
+ _alsa_driver->detach();
+ }
+
+ if (_jack_driver) {
+ _jack_driver->detach();
+ }
+
_main_win->hide();
}
@@ -898,15 +874,15 @@ Patchage::on_scroll(GdkEventScroll*)
void
Patchage::buffer_size_changed()
{
-#if defined(HAVE_JACK) || defined(HAVE_JACK_DBUS)
- const int selected = _buf_size_combo->get_active_row_number();
+ if (_jack_driver) {
+ const int selected = _buf_size_combo->get_active_row_number();
- if (selected == -1) {
- update_toolbar();
- } else {
- const uint32_t buffer_size = 1u << (selected + 5);
- _jack_driver->set_buffer_size(buffer_size);
- update_toolbar();
+ if (selected == -1) {
+ update_toolbar();
+ } else {
+ const uint32_t buffer_size = 1u << (selected + 5);
+ _jack_driver->set_buffer_size(buffer_size);
+ update_toolbar();
+ }
}
-#endif
}
diff --git a/src/Patchage.hpp b/src/Patchage.hpp
index 0e81afb..09e55fa 100644
--- a/src/Patchage.hpp
+++ b/src/Patchage.hpp
@@ -154,9 +154,6 @@ protected:
std::unique_ptr<Driver> _alsa_driver;
- void menu_alsa_connect();
- void menu_alsa_disconnect();
-
std::shared_ptr<PatchageCanvas> _canvas;
std::unique_ptr<AudioDriver> _jack_driver;
diff --git a/src/make_alsa_driver.hpp b/src/make_alsa_driver.hpp
new file mode 100644
index 0000000..4c21583
--- /dev/null
+++ b/src/make_alsa_driver.hpp
@@ -0,0 +1,42 @@
+/* This file is part of Patchage.
+ * Copyright 2007-2020 David Robillard <d@drobilla.net>
+ *
+ * Patchage is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option)
+ * any later version.
+ *
+ * Patchage is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef PATCHAGE_MAKE_ALSA_DRIVER_HPP
+#define PATCHAGE_MAKE_ALSA_DRIVER_HPP
+
+#include "Driver.hpp"
+#include "patchage_config.h"
+
+#include <memory>
+
+class ILog;
+
+#if defined(HAVE_ALSA)
+
+std::unique_ptr<Driver>
+make_alsa_driver(ILog& log, Driver::EventSink emit_event);
+
+#else
+
+inline std::unique_ptr<Driver>
+make_alsa_driver(ILog&, Driver::EventSink)
+{
+ return nullptr;
+}
+
+#endif
+
+#endif // PATCHAGE_MAKE_ALSA_DRIVER_HPP
diff --git a/src/make_jack_driver.hpp b/src/make_jack_driver.hpp
new file mode 100644
index 0000000..1099a18
--- /dev/null
+++ b/src/make_jack_driver.hpp
@@ -0,0 +1,42 @@
+/* This file is part of Patchage.
+ * Copyright 2007-2020 David Robillard <d@drobilla.net>
+ *
+ * Patchage is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option)
+ * any later version.
+ *
+ * Patchage is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef PATCHAGE_MAKE_JACK_DRIVER_HPP
+#define PATCHAGE_MAKE_JACK_DRIVER_HPP
+
+#include "AudioDriver.hpp"
+#include "patchage_config.h"
+
+#include <memory>
+
+class ILog;
+
+#if defined(PATCHAGE_LIBJACK) || defined(HAVE_JACK_DBUS)
+
+std::unique_ptr<AudioDriver>
+make_jack_driver(ILog& log, Driver::EventSink emit_event);
+
+#else
+
+inline std::unique_ptr<AudioDriver>
+make_jack_driver(ILog&, Driver::EventSink)
+{
+ return nullptr;
+}
+
+#endif
+
+#endif // PATCHAGE_MAKE_JACK_DRIVER_HPP