Loading...
Searching...
No Matches
MidiPortResolve.hpp
1#pragma once
2
8#include <libremidi/api.hpp>
9#include <libremidi/libremidi.hpp>
10#include <libremidi/port_comparison.hpp>
11
12#include <magic_enum/magic_enum.hpp>
13
14#include <optional>
15#include <span>
16#include <string>
17#include <vector>
18
19namespace Protocols::MIDIPorts
20{
21
31template <typename Port>
32std::optional<Port>
33resolvePort(Port wanted, libremidi::API api, const std::vector<Port>& live)
34{
35 if(live.empty())
36 return std::nullopt;
37
38 const std::span<const Port> ports{live.data(), live.size()};
39
40 // The lookup's heuristics all require the target to name our API.
41 if(wanted.api != api)
42 {
43 wanted.api = api;
44 wanted.port = static_cast<libremidi::port_handle>(-1);
45 }
46
47 if(auto found = libremidi::optimistic_serialized_port_lookup(wanted, ports);
48 !found.empty())
49 return *found.front();
50
51 wanted.port = static_cast<libremidi::port_handle>(-1);
52 if(auto found = libremidi::optimistic_serialized_port_lookup(wanted, ports);
53 !found.empty())
54 return *found.front();
55
56 return std::nullopt;
57}
58
59inline std::string describePort(const libremidi::port_information& p)
60{
61 if(!p.display_name.empty())
62 return p.display_name;
63 if(!p.port_name.empty())
64 return p.port_name;
65 return "<unnamed>";
66}
67
70inline std::string apiName(libremidi::API api)
71{
72 auto name = libremidi::get_api_display_name(api);
73 if(name.empty())
74 name = magic_enum::enum_name(api);
75 return std::string{name};
76}
77
78}