MayaFlux 0.2.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
MIDIBackend.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "InputBackend.hpp"
4
5class RtMidiIn;
6
7namespace MayaFlux::Core {
8
9/**
10 * @class MIDIBackend
11 * @brief RtMidi-based MIDI input backend
12 *
13 * Provides MIDI input functionality using RtMidi library. Supports:
14 * - Multiple simultaneous MIDI input ports
15 * - Port filtering by name
16 * - Virtual MIDI port creation
17 * - Automatic port detection
18 *
19 * Threading model:
20 * - RtMidi callbacks fire on RtMidi's internal threads
21 * - Callbacks push to InputManager's queue (thread-safe)
22 * - No separate polling thread needed (RtMidi is callback-driven)
23 */
24class MAYAFLUX_API MIDIBackend : public IInputBackend {
25public:
26 struct Config {
27 std::vector<std::string> input_port_filters;
28 std::vector<std::string> output_port_filters;
29 bool auto_open_inputs { true };
30 bool auto_open_outputs { false };
31 bool enable_virtual_port { false };
32 std::string virtual_port_name { "MayaFlux" };
33 };
34
36 explicit MIDIBackend(Config config);
37 ~MIDIBackend() override;
38
39 MIDIBackend(const MIDIBackend&) = delete;
43
44 // ===================================================================================
45 // IInputBackend Implementation
46 // ===================================================================================
47
48 bool initialize() override;
49 void start() override;
50 void stop() override;
51 void shutdown() override;
52
53 [[nodiscard]] bool is_initialized() const override { return m_initialized.load(); }
54 [[nodiscard]] bool is_running() const override { return m_running.load(); }
55
56 [[nodiscard]] std::vector<InputDeviceInfo> get_devices() const override;
57 size_t refresh_devices() override;
58
59 bool open_device(uint32_t device_id) override;
60 void close_device(uint32_t device_id) override;
61 [[nodiscard]] bool is_device_open(uint32_t device_id) const override;
62 [[nodiscard]] std::vector<uint32_t> get_open_devices() const override;
63
64 void set_input_callback(InputCallback callback) override;
65 void set_device_callback(DeviceCallback callback) override;
66
67 [[nodiscard]] InputType get_type() const override { return InputType::MIDI; }
68 [[nodiscard]] std::string get_name() const override { return "MIDI (RtMidi)"; }
69 [[nodiscard]] std::string get_version() const override;
70
71private:
73 unsigned int rtmidi_port_number;
74 };
75
77 std::unique_ptr<RtMidiIn> midi_in;
79 uint32_t device_id;
80 std::atomic<bool> active { false };
81
82 std::function<void(const InputValue&)> input_callback;
83 };
84
86 std::atomic<bool> m_initialized { false };
87 std::atomic<bool> m_running { false };
88
89 mutable std::mutex m_devices_mutex;
90 std::unordered_map<uint32_t, MIDIPortInfo> m_enumerated_devices;
91 std::unordered_map<uint32_t, std::shared_ptr<MIDIPortState>> m_open_devices;
92 uint32_t m_next_device_id { 1 };
93
96 mutable std::mutex m_callback_mutex;
97
98 bool port_matches_filter(const std::string& port_name) const;
99 uint32_t find_or_assign_device_id(unsigned int rtmidi_port);
100 void create_virtual_port_if_enabled();
101
102 static void rtmidi_callback(double timestamp, std::vector<unsigned char>* message, void* user_data);
103
104 void notify_device_change(const InputDeviceInfo& info, bool connected);
105
106 InputValue parse_midi_message(uint32_t device_id, const std::vector<unsigned char>& message) const;
107};
108
109} // namespace MayaFlux::Core
Abstract interface for input device backends.
bool is_initialized() const override
Check if backend is initialized.
MIDIBackend & operator=(const MIDIBackend &)=delete
bool is_running() const override
Check if backend is actively listening.
std::string get_name() const override
Get backend name/identifier string.
std::unordered_map< uint32_t, MIDIPortInfo > m_enumerated_devices
MIDIBackend(const MIDIBackend &)=delete
MIDIBackend & operator=(MIDIBackend &&)=delete
std::unordered_map< uint32_t, std::shared_ptr< MIDIPortState > > m_open_devices
DeviceCallback m_device_callback
MIDIBackend(MIDIBackend &&)=delete
InputType get_type() const override
Get backend type.
RtMidi-based MIDI input backend.
void initialize()
Definition main.cpp:11
InputType
Input backend type enumeration.
std::function< void(const InputValue &)> InputCallback
Callback signature for input events.
std::function< void(const InputDeviceInfo &, bool connected)> DeviceCallback
Callback signature for device connection/disconnection events.
Information about a connected input device.
Generic input value container.
std::vector< std::string > input_port_filters
std::vector< std::string > output_port_filters
std::function< void(const InputValue &)> input_callback
std::unique_ptr< RtMidiIn > midi_in