3#ifdef MAYAFLUX_PLATFORM_MACOS
7#include <CoreMIDI/CoreMIDI.h>
32class MAYAFLUX_API CoreMidiBackend :
public IInputBackend {
35 std::vector<std::string> input_port_filters;
36 std::vector<std::string> output_port_filters;
37 bool auto_open_inputs {
true };
38 bool auto_open_outputs {
false };
39 bool enable_virtual_port {
false };
40 bool enable_sysex {
true };
41 std::string virtual_port_name {
"MayaFlux" };
45 explicit CoreMidiBackend(Config config);
46 ~CoreMidiBackend()
override;
48 CoreMidiBackend(
const CoreMidiBackend&) =
delete;
49 CoreMidiBackend& operator=(
const CoreMidiBackend&) =
delete;
50 CoreMidiBackend(CoreMidiBackend&&) =
delete;
51 CoreMidiBackend& operator=(CoreMidiBackend&&) =
delete;
58 void start()
override;
62 [[nodiscard]]
bool is_initialized()
const override {
return m_initialized.load(); }
63 [[nodiscard]]
bool is_running()
const override {
return m_running.load(); }
65 [[nodiscard]] std::vector<InputDeviceInfo> get_devices()
const override;
66 size_t refresh_devices()
override;
68 bool open_device(uint32_t device_id)
override;
69 void close_device(uint32_t device_id)
override;
71 [[nodiscard]]
bool is_device_open(uint32_t device_id)
const override;
72 [[nodiscard]] std::vector<uint32_t> get_open_devices()
const override;
74 void set_input_callback(InputCallback callback)
override;
75 void set_device_callback(DeviceCallback callback)
override;
77 [[nodiscard]]
InputType get_type()
const override {
return InputType::MIDI; }
78 [[nodiscard]] std::string get_name()
const override {
return "MIDI (CoreMIDI)"; }
79 [[nodiscard]] std::string get_version()
const override;
82 struct MIDIPortInfo : InputDeviceInfo {
83 MIDIUniqueID unique_id { 0 };
84 MIDIEndpointRef endpoint { 0 };
87 struct MIDIPortState {
89 uint32_t device_id { 0 };
91 MIDIPortRef input_port { 0 };
93 std::atomic<bool> active {
false };
95 std::function<void(
const InputValue&)> input_callback;
100 std::atomic<bool> m_initialized {
false };
101 std::atomic<bool> m_running {
false };
103 MIDIClientRef m_client { 0 };
104 MIDIEndpointRef m_virtual_destination { 0 };
106 mutable std::mutex m_devices_mutex;
107 std::unordered_map<uint32_t, MIDIPortInfo> m_enumerated_devices;
108 std::unordered_map<uint32_t, std::shared_ptr<MIDIPortState>> m_open_devices;
109 uint32_t m_next_device_id { 1 };
113 mutable std::mutex m_callback_mutex;
115 bool port_matches_filter(
const std::string& port_name)
const;
116 uint32_t find_or_assign_device_id(MIDIUniqueID unique_id);
118 void create_virtual_port_if_enabled();
119 void notify_device_change(
const InputDeviceInfo& info,
bool connected);
121 static void virtual_destination_callback(
122 const MIDIPacketList* packet_list,
123 void* read_proc_ref_con,
124 void* src_conn_ref_con);
126 static void midi_read_callback(
127 const MIDIPacketList* packet_list,
128 void* read_proc_ref_con,
129 void* src_conn_ref_con);
131 static void midi_notify_callback(
132 const MIDINotification* notification,
135 void destroy_open_port(MIDIPortState& state);
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.
void stop()
Stop all Portal::Graphics operations.
bool is_initialized()
Checks if the default engine has been initialized.