3#ifdef MAYAFLUX_PLATFORM_WINDOWS
32class MAYAFLUX_API WinMmMidiBackend :
public IInputBackend {
35 std::vector<std::string> input_port_filters;
36 bool auto_open_inputs {
true };
37 bool enable_sysex {
true };
38 std::string virtual_port_name {
"MayaFlux" };
42 explicit WinMmMidiBackend(Config config);
43 ~WinMmMidiBackend()
override;
45 WinMmMidiBackend(
const WinMmMidiBackend&) =
delete;
46 WinMmMidiBackend& operator=(
const WinMmMidiBackend&) =
delete;
47 WinMmMidiBackend(WinMmMidiBackend&&) =
delete;
48 WinMmMidiBackend& operator=(WinMmMidiBackend&&) =
delete;
51 void start()
override;
55 [[nodiscard]]
bool is_initialized()
const override {
return m_initialized.load(); }
56 [[nodiscard]]
bool is_running()
const override {
return m_running.load(); }
58 [[nodiscard]] std::vector<InputDeviceInfo> get_devices()
const override;
59 size_t refresh_devices()
override;
61 bool open_device(uint32_t device_id)
override;
62 void close_device(uint32_t device_id)
override;
63 [[nodiscard]]
bool is_device_open(uint32_t device_id)
const override;
64 [[nodiscard]] std::vector<uint32_t> get_open_devices()
const override;
66 void set_input_callback(InputCallback
callback)
override;
67 void set_device_callback(DeviceCallback
callback)
override;
69 [[nodiscard]]
InputType get_type()
const override {
return InputType::MIDI; }
70 [[nodiscard]] std::string get_name()
const override {
return "MIDI (WinMM)"; }
71 [[nodiscard]] std::string get_version()
const override;
74 static constexpr size_t k_sysex_buf_size { 256 };
75 static constexpr size_t k_sysex_buf_count { 2 };
77 struct MIDIPortInfo : InputDeviceInfo {
78 UINT winmm_device_id { 0 };
81 struct MIDIPortState {
83 uint32_t device_id { 0 };
84 HMIDIIN handle {
nullptr };
85 std::atomic<bool> active {
false };
86 std::function<void(
const InputValue&)> input_callback;
87 MIDIHDR sysex_headers[k_sysex_buf_count] {};
88 std::array<std::vector<uint8_t>, k_sysex_buf_count> sysex_bufs;
92 std::atomic<bool> m_initialized {
false };
93 std::atomic<bool> m_running {
false };
95 mutable std::mutex m_devices_mutex;
96 std::unordered_map<uint32_t, MIDIPortInfo> m_enumerated_devices;
97 std::unordered_map<uint32_t, std::shared_ptr<MIDIPortState>> m_open_devices;
98 uint32_t m_next_device_id { 1 };
102 mutable std::mutex m_callback_mutex;
104 bool port_matches_filter(
const std::string&
name)
const;
105 uint32_t find_or_assign_device_id(UINT winmm_id);
106 void queue_sysex_buffers(MIDIPortState& state);
107 void notify_device_change(
const InputDeviceInfo& info,
bool connected);
109 static void CALLBACK midi_callback(HMIDIIN handle, UINT msg,
110 DWORD_PTR user_data, DWORD_PTR param1, DWORD_PTR param2);
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.
@ CALLBACK
Use callback for custom transition.
void stop()
Stop all Portal::Graphics operations.
bool is_initialized()
Checks if the default engine has been initialized.