summaryrefslogtreecommitdiffstats
path: root/src/AlsaDriver.cpp
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2020-11-29 18:02:59 +0100
committerDavid Robillard <d@drobilla.net>2020-11-29 18:03:31 +0100
commitb848d9ccbd94f88e3b1b9f1884a05efcea377dfc (patch)
tree6a859e66e613061b1abcebb13fada336982efbac /src/AlsaDriver.cpp
parent9964717f1c5bf56f24c81ff5597085a62e966a7b (diff)
downloadpatchage-b848d9ccbd94f88e3b1b9f1884a05efcea377dfc.tar.gz
patchage-b848d9ccbd94f88e3b1b9f1884a05efcea377dfc.tar.bz2
patchage-b848d9ccbd94f88e3b1b9f1884a05efcea377dfc.zip
Completely isolate drivers from the rest of the application
Diffstat (limited to 'src/AlsaDriver.cpp')
-rw-r--r--src/AlsaDriver.cpp62
1 files changed, 61 insertions, 1 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)}};
+}