2424 LIBREMIDI_STATIC constexpr const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}
2525
2626NAMESPACE_LIBREMIDI {
27- LIBREMIDI_DEFINE_GUID_CONSTEXPR (IID, IID_IMidiEndpointConnectionMessagesReceivedCallback, 0x8087b303 ,0x0519 ,0x31d1 ,0x31 ,0xd1 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x10 );
28- LIBREMIDI_DEFINE_GUID_CONSTEXPR (IID, IID_IMidiEndpointConnectionRaw, 0x8087b303 ,0x0519 ,0x31d1 ,0x31 ,0xd1 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x20 );
29- LIBREMIDI_DEFINE_GUID_CONSTEXPR (IID, IID_IMidiClientInitializer, 0x8087b303 , 0xd551 , 0xbce2 , 0x1e , 0xad , 0xa2 , 0x50 , 0x0d , 0x50 , 0xc5 , 0x80 );
30- LIBREMIDI_DEFINE_GUID_CONSTEXPR (IID, IID_MidiClientInitializerUuid, 0xc3263827 , 0xc3b0 , 0xbdbd , 0x25 , 0x00 , 0xce , 0x63 , 0xa3 , 0xf3 , 0xf2 , 0xc3 );
27+ LIBREMIDI_DEFINE_GUID_CONSTEXPR (IID, IID_IMidiEndpointConnectionMessagesReceivedCallback, 0x8087b303 , 0x0519 , 0x31d1 , 0x31 , 0xd1 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 );
28+ LIBREMIDI_DEFINE_GUID_CONSTEXPR (IID, IID_IMidiEndpointConnectionRaw, 0x8087b303 , 0x0519 , 0x31d1 , 0x31 , 0xd1 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x20 );
29+ LIBREMIDI_DEFINE_GUID_CONSTEXPR (IID, IID_IMidiClientInitializer, 0x8087b303 , 0xd551 , 0xbce2 , 0x1e , 0xad , 0xa2 , 0x50 , 0x0d , 0x50 , 0xc5 , 0x80 );
30+ LIBREMIDI_DEFINE_GUID_CONSTEXPR (IID, IID_MidiClientInitializerUuid, 0xc3263827 , 0xc3b0 , 0xbdbd , 0x25 , 0x00 , 0xce , 0x63 , 0xa3 , 0xf3 , 0xf2 , 0xc3 );
31+ LIBREMIDI_DEFINE_GUID_CONSTEXPR (IID, IID_MidiSrvTransportUuid, 0x2ba15e4e , 0x5417 , 0x4a66 , 0x85 , 0xb8 , 0x2b , 0x22 , 0x60 , 0xef , 0xbc , 0x84 );
3132}
3233#endif
3334
34- #include < init/Microsoft.Windows.Devices.Midi2.Initialization.hpp>
3535// clang-format on
3636
3737namespace midi2 = winrt::Microsoft::Windows::Devices::Midi2;
@@ -44,7 +44,6 @@ using namespace winrt::Windows::Foundation;
4444using namespace winrt ::Windows::Devices::Enumeration;
4545using namespace winrt ::Windows::Storage::Streams;
4646using namespace winrt ::Microsoft::Windows::Devices::Midi2;
47- using namespace ::Microsoft::Windows::Devices::Midi2::Initialization;
4847
4948inline bool ichar_equals (char a, char b)
5049{
@@ -82,16 +81,138 @@ get_port(const std::string& device_name, int group_terminal_block)
8281 }
8382 return {nullptr , nullptr };
8483}
84+
85+ // From Microsoft.Windows.Devices.Midi2.Initialization.hpp
86+ typedef enum
87+ {
88+ Platform_x64 = 1 ,
89+ // Platform_Arm64 = 2,
90+ // Platform_Arm64EC = 3,
91+ Platform_Arm64X = 4 ,
92+ } MidiAppSDKPlatform;
93+
94+ struct IMidiClientInitializer : ::IUnknown
95+ {
96+ // returns the SDK version info. Supply nullptr for arguments you don't care about
97+ STDMETHOD (GetInstalledWindowsMidiServicesSdkVersion)(
98+ MidiAppSDKPlatform* buildPlatform,
99+ USHORT* versionMajor,
100+ USHORT* versionMinor,
101+ USHORT* versionPatch,
102+
103+ LPWSTR* buildSource,
104+ LPWSTR* versionName,
105+ LPWSTR* versionFullString
106+ ) = 0 ;
107+
108+ // demand-starts the service if present
109+ STDMETHOD (EnsureServiceAvailable)() = 0 ;
110+ };
111+ struct winmidi_shared_data_instance
112+ {
113+ IMidiClientInitializer* initializer{nullptr };
114+ bool ready{false };
115+ winmidi_shared_data_instance ()
116+ {
117+ // 1. Check if MIDI Services are available
118+ {
119+ ::IUnknown* servicePointer{ nullptr };
120+ auto hr = CoCreateInstance (
121+ libremidi::IID_MidiSrvTransportUuid,
122+ NULL ,
123+ CLSCTX_INPROC_SERVER,
124+ IID_PPV_ARGS (&servicePointer)
125+ );
126+
127+ if (SUCCEEDED (hr))
128+ {
129+ if (servicePointer == nullptr )
130+ {
131+ ready = false ;
132+ return ;
133+ }
134+
135+ // Here is the good case:
136+ servicePointer->Release ();
137+ servicePointer = nullptr ;
138+ ready = true ;
139+ }
140+ else if (hr == REGDB_E_CLASSNOTREG)
141+ {
142+ servicePointer = nullptr ;
143+ ready = false ;
144+ return ;
145+ }
146+ else
147+ {
148+ servicePointer = nullptr ;
149+ ready = false ;
150+ return ;
151+ }
152+ }
153+
154+ // 2. Check if MIDI services can be created
155+ {
156+ if (SUCCEEDED (CoCreateInstance (
157+ libremidi::IID_MidiClientInitializerUuid,
158+ NULL ,
159+ CLSCTX::CLSCTX_INPROC_SERVER | CLSCTX::CLSCTX_FROM_DEFAULT_CONTEXT,
160+ libremidi::IID_IMidiClientInitializer,
161+ reinterpret_cast <void **>(&initializer)
162+ )))
163+ {
164+ if (initializer != nullptr )
165+ {
166+ ready = true ;
167+ }
168+ else
169+ {
170+ ready = false ;
171+ return ;
172+ }
173+ }
174+ else
175+ {
176+ ready = false ;
177+ return ;
178+ }
179+ }
180+
181+ // 3. Check if MIDI services can be used
182+ if (SUCCEEDED (initializer->EnsureServiceAvailable ()))
183+ {
184+ ready = true ;
185+ }
186+ else
187+ {
188+ ready = false ;
189+ initializer->Release ();
190+ initializer = nullptr ;
191+ return ;
192+ }
193+ }
194+
195+ ~winmidi_shared_data_instance ()
196+ {
197+ if (initializer != nullptr )
198+ {
199+ initializer->Release ();
200+ initializer = nullptr ;
201+ }
202+ }
203+ };
204+
85205struct winmidi_shared_data
86206{
87- std::shared_ptr<MidiDesktopAppSdkInitializer> initializer ;
88- bool m_ready{ false };
207+ std::shared_ptr<winmidi_shared_data_instance> self = libremidi::instance<winmidi_shared_data_instance>() ;
208+
89209 winmidi_shared_data ()
90- : initializer{libremidi::instance<MidiDesktopAppSdkInitializer>()}
91- , m_ready{
92- initializer && initializer-> InitializeSdkRuntime ()
93- && initializer-> EnsureServiceAvailable ()}
210+ {
211+ }
212+
213+ ~winmidi_shared_data ()
94214 {
95215 }
96216};
217+
97218}
0 commit comments