diff --git a/include/libremidi/libremidi.cpp b/include/libremidi/libremidi.cpp index dcce6eb..3cb79ae 100644 --- a/include/libremidi/libremidi.cpp +++ b/include/libremidi/libremidi.cpp @@ -59,7 +59,7 @@ libremidi::API midi_api(const std::any& conf) libremidi::API ret = libremidi::API::UNSPECIFIED; midi_any::for_all_backends([&](T) { if (std::any_cast(&conf) - || std::any_cast(&conf) + || std::any_cast(&conf) || std::any_cast(&conf)) { ret = T::API; diff --git a/include/libremidi/midi_in.cpp b/include/libremidi/midi_in.cpp index f47606e..f1c854c 100644 --- a/include/libremidi/midi_in.cpp +++ b/include/libremidi/midi_in.cpp @@ -228,14 +228,47 @@ make_midi2_in(const ump_input_configuration& base_conf, const std::any& api_conf { return make_midi2_in(base_conf); } - else if (auto api = std::any_cast(&api_conf)) + else if (auto api_p = std::any_cast(&api_conf)) { - return make_midi_in(base_conf, midi_in_configuration_for(*api), midi2::available_backends); + if (*api_p == libremidi::API::UNSPECIFIED) + { + if (auto backend = make_midi_in( + base_conf, midi_in_configuration_for(libremidi::midi2::default_api()), + midi2::available_backends)) + return backend; + + auto c2 = convert_midi2_to_midi1_input_configuration(base_conf); + if (auto backend = make_midi_in( + c2, midi_in_configuration_for(libremidi::midi1::default_api()), + midi1::available_backends)) + return backend; + } + else if (is_midi2(*api_p)) + { + // all good + return make_midi_in(base_conf, midi_in_configuration_for(*api_p), midi2::available_backends); + } + else if (is_midi1(*api_p)) + { + auto c2 = convert_midi2_to_midi1_input_configuration(base_conf); + return make_midi_in(c2, midi_in_configuration_for(*api_p), midi1::available_backends); + } } else { - return make_midi_in(base_conf, api_conf, midi2::available_backends); + const auto api = libremidi::midi_api(api_conf); + if (libremidi::is_midi2(api)) + { + return make_midi_in(base_conf, api_conf, midi2::available_backends); + } + else if (libremidi::is_midi1(api)) + { + auto c2 = convert_midi2_to_midi1_input_configuration(base_conf); + return make_midi_in(c2, api_conf, midi1::available_backends); + } } + + return std::make_unique(input_configuration{}, dummy_configuration{}); } /// MIDI 2 constructors diff --git a/include/libremidi/midi_out.cpp b/include/libremidi/midi_out.cpp index 74dcc74..48329c3 100644 --- a/include/libremidi/midi_out.cpp +++ b/include/libremidi/midi_out.cpp @@ -64,9 +64,24 @@ make_midi_out(const output_configuration& base_conf, const std::any& api_conf) { return make_midi_out(base_conf); } - else if (auto api = std::any_cast(&api_conf)) + else if (auto api_p = std::any_cast(&api_conf)) { - return make_midi_out_impl(base_conf, midi_out_configuration_for(*api)); + if (*api_p == libremidi::API::UNSPECIFIED) + { + if (auto backend = make_midi_out_impl( + base_conf, midi_out_configuration_for(libremidi::midi1::default_api()))) + return backend; + + if (auto backend = make_midi_out_impl( + base_conf, midi_out_configuration_for(libremidi::midi2::default_api()))) + return backend; + + return std::make_unique(output_configuration{}, dummy_configuration{}); + } + else + { + return make_midi_out_impl(base_conf, midi_out_configuration_for(*api_p)); + } } else { diff --git a/include/libremidi/observer.cpp b/include/libremidi/observer.cpp index 72972f6..f9c66ab 100644 --- a/include/libremidi/observer.cpp +++ b/include/libremidi/observer.cpp @@ -53,15 +53,30 @@ LIBREMIDI_INLINE auto make_observer_impl(auto base_conf, std::any api_conf) return ptr; } -LIBREMIDI_INLINE auto make_observer(auto base_conf, std::any api_conf) +LIBREMIDI_INLINE std::unique_ptr make_observer(auto base_conf, std::any api_conf) { if (!api_conf.has_value()) { return make_observer(base_conf); } - else if (auto api = std::any_cast(&api_conf)) + else if (auto api_p = std::any_cast(&api_conf)) { - return make_observer_impl(base_conf, observer_configuration_for(*api)); + if (*api_p == libremidi::API::UNSPECIFIED) + { + if (auto backend = make_observer_impl( + base_conf, observer_configuration_for(libremidi::midi1::default_api()))) + return backend; + + if (auto backend = make_observer_impl( + base_conf, observer_configuration_for(libremidi::midi2::default_api()))) + return backend; + + return std::make_unique(observer_configuration{}, dummy_configuration{}); + } + else + { + return make_observer_impl(base_conf, observer_configuration_for(*api_p)); + } } else {