libremidi update to v5.4.3 and added virtual midi out as default

This commit is contained in:
Sebastian
2026-06-23 00:05:41 +02:00
parent dc0003232a
commit 51cd271b6f
166 changed files with 8135 additions and 2009 deletions
+56 -12
View File
@@ -1,16 +1,17 @@
#pragma once
#include <libremidi/detail/ump_stream.hpp>
#include <libremidi/backends/winmidi/config.hpp>
#include <libremidi/backends/winmidi/helpers.hpp>
#include <libremidi/backends/winmidi/observer.hpp>
#include <libremidi/detail/midi_out.hpp>
#include <libremidi/detail/ump_stream.hpp>
namespace libremidi::winmidi
NAMESPACE_LIBREMIDI::winmidi
{
class midi_out_impl final
: public midi2::out_api
, public error_handler
, public winmidi_shared_data
{
public:
struct
@@ -21,7 +22,9 @@ public:
midi_out_impl(libremidi::output_configuration&& conf, winmidi::output_configuration&& apiconf)
: configuration{std::move(conf), std::move(apiconf)}
, m_session{MidiSession::CreateSession(L"libremidi session")}
, m_session{
configuration.context ? *configuration.context
: MidiSession::Create(to_hstring(configuration.client_name))}
{
this->client_open_ = stdx::error{};
}
@@ -35,11 +38,18 @@ public:
stdx::error open_port(const output_port& port, std::string_view) override
{
auto ep = get_port_by_name(port.port_name);
if (!ep)
auto device_id = get_if<std::string>(&port.device);
if (!device_id)
return std::errc::invalid_argument;
auto [ep, gp] = get_port(*device_id, port.port);
if (!ep || !gp)
return std::errc::address_not_available;
m_endpoint = m_session.CreateEndpointConnection(ep.Id());
m_endpoint = m_session.CreateEndpointConnection(ep.EndpointDeviceId());
#if LIBREMIDI_WINMIDI_HAS_COM_EXTENSIONS
m_endpoint.as(libremidi::IID_IMidiEndpointConnectionRaw, m_raw_endpoint.put_void());
#endif
m_endpoint.Open();
return stdx::error{};
@@ -47,6 +57,9 @@ public:
stdx::error close_port() override
{
if(!m_endpoint)
return std::errc::not_connected;
m_session.DisconnectEndpointConnection(m_endpoint.ConnectionId());
return stdx::error{};
}
@@ -54,8 +67,10 @@ public:
stdx::error send_ump(const uint32_t* message, size_t size) override
{
auto write_func = [this](const uint32_t* ump, int64_t bytes) -> std::errc {
#if !LIBREMIDI_WINMIDI_HAS_COM_EXTENSIONS
MidiSendMessageResults ret{};
switch(bytes / 4)
switch (bytes / 4)
{
case 1:
ret = m_endpoint.SendSingleMessagePacket(MidiMessage32(0, ump[0]));
@@ -67,23 +82,52 @@ public:
ret = m_endpoint.SendSingleMessagePacket(MidiMessage96(0, ump[0], ump[1], ump[2]));
break;
case 4:
ret = m_endpoint.SendSingleMessagePacket(MidiMessage128(0, ump[0], ump[1], ump[2], ump[3]));
ret = m_endpoint.SendSingleMessagePacket(
MidiMessage128(0, ump[0], ump[1], ump[2], ump[3]));
break;
default:
return std::errc::bad_message;
}
if(ret != MidiSendMessageResults::Succeeded)
if (ret != MidiSendMessageResults::Succeeded)
return std::errc::bad_message;
#else
HRESULT ret{};
switch (bytes / 4)
{
case 1:
assert( m_raw_endpoint->ValidateBufferHasOnlyCompleteUmps(1, (UINT32*)ump));
ret = m_raw_endpoint->SendMidiMessagesRaw(0, 1, (UINT32*)ump);
break;
case 2:
assert( m_raw_endpoint->ValidateBufferHasOnlyCompleteUmps(2, (UINT32*)ump));
ret = m_raw_endpoint->SendMidiMessagesRaw(0, 2, (UINT32*)ump);
break;
case 3:
assert( m_raw_endpoint->ValidateBufferHasOnlyCompleteUmps(3, (UINT32*)ump));
ret = m_raw_endpoint->SendMidiMessagesRaw(0, 3, (UINT32*)ump);
break;
case 4:
assert( m_raw_endpoint->ValidateBufferHasOnlyCompleteUmps(4, (UINT32*)ump));
ret = m_raw_endpoint->SendMidiMessagesRaw(0, 4, (UINT32*)ump);
break;
default:
return std::errc::bad_message;
}
#endif
if(ret < 0)
return std::errc::io_error;
return std::errc{0};
};
return segment_ump_stream(message, size, write_func, []() {});
return segment_ump_stream(message, size, write_func, []() { });
}
private:
MidiSession m_session;
winrt::Windows::Devices::Midi2::MidiEndpointConnection m_endpoint{nullptr};
winrt::Microsoft::Windows::Devices::Midi2::MidiEndpointConnection m_endpoint{nullptr};
#if LIBREMIDI_WINMIDI_HAS_COM_EXTENSIONS
winrt::impl::com_ref<IMidiEndpointConnectionRaw> m_raw_endpoint{};
#endif
};
}