From 49880b85de3d18f21792b9333571a396975697a0 Mon Sep 17 00:00:00 2001 From: Eddy Pedroni Date: Thu, 24 Jul 2025 07:27:51 +0200 Subject: Add udev notification support for connecting/disconnecting devices --- daemon/src/connection_manager.cpp | 69 ++++++++------------------------- daemon/src/connection_manager.h | 8 ++-- daemon/src/device_connection.h | 81 +++++++++++++++++++++++++++++++++++++++ daemon/src/main.cpp | 2 +- 4 files changed, 101 insertions(+), 59 deletions(-) create mode 100644 daemon/src/device_connection.h (limited to 'daemon/src') diff --git a/daemon/src/connection_manager.cpp b/daemon/src/connection_manager.cpp index 6de1800..ac4c6cb 100644 --- a/daemon/src/connection_manager.cpp +++ b/daemon/src/connection_manager.cpp @@ -1,41 +1,15 @@ #include "connection_manager.h" -#include "sender.h" +#include "device_connection.h" + +#include "udevw/include/udevw.hpp" #include -#include +#include namespace midi_router { -struct Device_Connection : public Sender -{ - Device_Connection(Device_Id const & source_id, Submitter & submitter): - source_id(source_id), - submitter(submitter) - {} - - Device_Id const & source_id; - Submitter & submitter; - RtMidiIn midi_in {}; - RtMidiOut midi_out {}; - - void - send(std::vector const & payload) override - { - if (midi_out.isPortOpen()) - { - midi_out.sendMessage(&payload); - } - } - - std::string - get_id() const override - { - return source_id; - } -}; - static void callback(double time_stamp, std::vector *raw, void *user_data) { @@ -56,26 +30,13 @@ callback(double time_stamp, std::vector *raw, void *user_data) Connection_Manager::Connection_Manager(Device_Map const & device_map, Submitter & submitter): m_device_map(device_map), m_submitter(submitter), - m_connections{} + m_connections{}, + m_detector(std::bind(&Connection_Manager::detect_devices, this)) { for (auto const & [name, id] : device_map) { - m_connections[id] = std::make_unique(id, submitter); - auto & connection = m_connections[id]; - - connection->midi_in.setCallback(&callback, connection.get()); - connection->midi_in.ignoreTypes(true, false, true); - - if (!open_port(&connection->midi_in, name)) - { - std::cerr << "Input port not found for device " << name << "\n"; - } - - if (!open_port(&connection->midi_out, name)) - { - std::cerr << "Output port not found for device " << name << "\n"; - } - + m_connections[id] = std::make_unique(id, name, submitter, callback); + m_connections[id]->open(); } } @@ -87,18 +48,18 @@ Connection_Manager::get_sender(Device_Id const & device) const return *m_connections.at(device); } -bool -Connection_Manager::open_port(RtMidi* const midi, std::string const & name) +void +Connection_Manager::detect_devices() { - for (std::size_t i = 0; i < midi->getPortCount(); ++i) + while (true) { - if (midi->getPortName(i).contains(name)) + std::cout << "Polling for devices\n"; + std::this_thread::sleep_for(std::chrono::seconds(1)); + for (auto && [id, connection] : m_connections) { - midi->openPort(i); - return true; + connection->open(); } } - return false; } } // namespace midi_router diff --git a/daemon/src/connection_manager.h b/daemon/src/connection_manager.h index e15eaaa..21977a4 100644 --- a/daemon/src/connection_manager.h +++ b/daemon/src/connection_manager.h @@ -7,8 +7,7 @@ #include #include #include - -class RtMidi; +#include namespace midi_router { @@ -26,12 +25,13 @@ public: get_sender(Device_Id const & device) const; private: - static bool - open_port(RtMidi* const midi, std::string const & name); + void + detect_devices(); Device_Map const & m_device_map; Submitter & m_submitter; std::map> m_connections; + std::thread m_detector; }; } // namespace midi_router diff --git a/daemon/src/device_connection.h b/daemon/src/device_connection.h new file mode 100644 index 0000000..17e354d --- /dev/null +++ b/daemon/src/device_connection.h @@ -0,0 +1,81 @@ +#pragma once + +#include "types.h" +#include "submitter.h" +#include "sender.h" + +#include + +#include + +namespace midi_router +{ + +struct Device_Connection : public Sender +{ + Device_Connection(Device_Id const & source_id, std::string const & device_name, Submitter & submitter, RtMidiIn::RtMidiCallback callback): + source_id(source_id), + device_name(device_name), + submitter(submitter) + { + midi_in.setCallback(callback, this); + midi_in.ignoreTypes(true, false, true); + } + + Device_Id const & source_id; + std::string const & device_name; + Submitter & submitter; + RtMidiIn midi_in {}; + RtMidiOut midi_out {}; + + void + send(std::vector const & payload) override + { + midi_out.sendMessage(&payload); + } + + std::string + get_id() const override + { + return source_id; + } + + void + open() + { + if (!open_port(midi_in, device_name)) + { + std::cerr << "Input port not found for device " << device_name << "\n"; + } + + if (!open_port(midi_out, device_name)) + { + std::cerr << "Output port not found for device " << device_name << "\n"; + } + } + + void + close() + { + midi_in.closePort(); + midi_out.closePort(); + } + +private: + bool + open_port(RtMidi & midi, std::string const & name) + { + for (std::size_t i = 0; i < midi.getPortCount(); ++i) + { + if (midi.getPortName(i).contains(name)) + { + midi.openPort(i); + return true; + } + } + return false; + } +}; + +} // namespace midi_router + diff --git a/daemon/src/main.cpp b/daemon/src/main.cpp index 8ca0dd6..f131f92 100644 --- a/daemon/src/main.cpp +++ b/daemon/src/main.cpp @@ -9,7 +9,7 @@ using namespace midi_router; -bool verbose = false; +bool verbose = true; int main() { -- cgit v1.2.3