packages feed

libremidi 0.4.1 → 0.4.2

raw patch · 37 files changed

+470/−203 lines, 37 files

Files

libremidi.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack  name:           libremidi-version:        0.4.1+version:        0.4.2 synopsis:       libremidi bindings for haskell description:    Please see the README on GitHub at <https://github.com/ejconlon/libremidi-haskell#readme> homepage:       https://github.com/ejconlon/libremidi-haskell#readme
src/Libremidi/Api.hs view
@@ -3,6 +3,7 @@ -- Operations in ErrM can possibly fail. module Libremidi.Api where +import Control.Monad ((>=>)) import Control.Monad.IO.Class (liftIO) import Data.Coerce (coerce) import Data.Default (Default (..))@@ -31,6 +32,7 @@   , fromCLong   , pokeField   , takeM+  , text0M   , textM   , toCBool   , toCLong@@ -76,10 +78,14 @@   | ApiWindowsUwp   | ApiWebmidi   | ApiPipewire+  | ApiKeyboard+  | ApiNetwork   | ApiAlsaRawUmp   | ApiAlsaSeqUmp   | ApiCoremidiUmp   | ApiWindowsMidiServices+  | ApiKeyboardUmp+  | ApiNetworkUmp   | ApiDummy   deriving stock (Eq, Ord, Show, Enum, Bounded) @@ -94,10 +100,14 @@     a | a == LMF.apiWindowsUwp -> Just ApiWindowsUwp     a | a == LMF.apiWebmidi -> Just ApiWebmidi     a | a == LMF.apiPipewire -> Just ApiPipewire+    a | a == LMF.apiKeyboard -> Just ApiKeyboard+    a | a == LMF.apiNetwork -> Just ApiNetwork     a | a == LMF.apiAlsaRawUmp -> Just ApiAlsaRawUmp     a | a == LMF.apiAlsaSeqUmp -> Just ApiAlsaSeqUmp     a | a == LMF.apiCoremidiUmp -> Just ApiCoremidiUmp     a | a == LMF.apiWindowsMidiServices -> Just ApiWindowsMidiServices+    a | a == LMF.apiKeyboardUmp -> Just ApiKeyboardUmp+    a | a == LMF.apiNetworkUmp -> Just ApiNetworkUmp     a | a == LMF.apiDummy -> Just ApiDummy     _ -> Nothing   toBitEnum = \case@@ -110,10 +120,14 @@     ApiWindowsUwp -> LMF.apiWindowsUwp     ApiWebmidi -> LMF.apiWebmidi     ApiPipewire -> LMF.apiPipewire+    ApiKeyboard -> LMF.apiKeyboard+    ApiNetwork -> LMF.apiNetwork     ApiAlsaRawUmp -> LMF.apiAlsaRawUmp     ApiAlsaSeqUmp -> LMF.apiAlsaSeqUmp     ApiCoremidiUmp -> LMF.apiCoremidiUmp     ApiWindowsMidiServices -> LMF.apiWindowsMidiServices+    ApiKeyboardUmp -> LMF.apiKeyboardUmp+    ApiNetworkUmp -> LMF.apiNetworkUmp     ApiDummy -> LMF.apiDummy  data ConfigType@@ -507,3 +521,31 @@ outSchedMsg2 h ts msg len = unRunErrM $   withForeignPtr h $ \p ->     checkM (LMF.libremidi_midi_out_schedule_ump p (toCLong ts) msg (toCSize (fromIntegral len)))++getVersion :: IO Text+getVersion = LMF.libremidi_get_version >>= text0M++type AvailFun = Maybe Api -> IO ()++newAvailCb :: AvailFun -> IO (Cb LMF.AvailFun)+newAvailCb f = LMF.newAvailCb (\_ -> f . fromBitEnum)++availApis1 :: AvailFun -> IO ()+availApis1 f = do+  cb <- newAvailCb f+  withCb cb (LMF.libremidi_midi1_available_apis nullPtr)++availApis2 :: AvailFun -> IO ()+availApis2 f = do+  cb <- newAvailCb f+  withCb cb (LMF.libremidi_midi2_available_apis nullPtr)++apiIdentifier :: Api -> IO Text+apiIdentifier = LMF.libremidi_api_identifier . toBitEnum >=> text0M++apiDisplayName :: Api -> IO Text+apiDisplayName = LMF.libremidi_api_display_name . toBitEnum >=> text0M++getCompiledApiByIdentifier :: Text -> IO (Maybe Api)+getCompiledApiByIdentifier n =+  TF.withCString n (fmap fromBitEnum . LMF.libremidi_get_compiled_api_by_identifier)
src/Libremidi/Common.hs view
@@ -5,7 +5,6 @@ import Control.Exception (Exception, finally, mask, mask_, throwIO) import Control.Monad.Except (ExceptT (..), MonadError (..), runExceptT) import Control.Monad.IO.Class (MonadIO (..))-import Data.Coerce (coerce) import Data.Foldable (traverse_) import Data.Int (Int32, Int64) import Data.Kind (Type)@@ -190,6 +189,15 @@     then fmap Right two     else pure (Left e) +-- TODO use TF.peekCString when available in text 2.1.2+foreign import ccall "string.h strlen"+  strlen :: CString -> IO CSize++text0M :: CString -> IO Text+text0M s = do+  l <- strlen s+  TF.peekCStringLen (s, fromIntegral l)+ textM :: (Ptr CString -> Ptr CSize -> IO Err) -> ErrM Text textM f = unRunErrM $   allocaPtr $ \sptr -> do@@ -197,7 +205,7 @@       checkAndThenM (f sptr lptr) $ do         s <- peek sptr         l <- peek lptr-        TF.fromPtr (coerce s) (fromIntegral l)+        TF.peekCStringLen (s, fromIntegral l)  takeM :: (Ptr (Ptr x) -> IO Err) -> ErrM (ForeignPtr x) takeM f = unRunErrM $
src/Libremidi/Foreign.hsc view
@@ -10,6 +10,7 @@ import Foreign.Ptr (Ptr, FunPtr) import Libremidi.Common (Err (..), Field, Cb, mallocForeignPtrBytes0, newCb, ptrSize, MallocPtr (..), newField) +#include "libremidi/api-c.h" #include "libremidi/libremidi-c.h"  #{enum TimestampMode@@ -35,10 +36,14 @@  , apiWindowsUwp = WINDOWS_UWP  , apiWebmidi = WEBMIDI  , apiPipewire = PIPEWIRE+ , apiKeyboard = KEYBOARD+ , apiNetwork = NETWORK  , apiAlsaRawUmp = ALSA_RAW_UMP  , apiAlsaSeqUmp = ALSA_SEQ_UMP  , apiCoremidiUmp = COREMIDI_UMP  , apiWindowsMidiServices = WINDOWS_MIDI_SERVICES+ , apiKeyboardUmp = KEYBOARD_UMP+ , apiNetworkUmp = NETWORK_UMP  , apiDummy = DUMMY } @@ -75,6 +80,7 @@  data ApiConfig +-- TODO Use libremidi_midi_api_configuration_init instance MallocPtr ApiConfig where   mallocPtr _ = mallocForeignPtrBytes0 #{size libremidi_api_configuration} @@ -103,8 +109,17 @@ newObsCb :: ObsFun p -> IO (Cb (ObsFun p)) newObsCb = newCb obsWrap +type AvailFun = Ptr Void -> Api -> IO ()++foreign import ccall "wrapper"+  availWrap :: AvailFun -> IO (FunPtr AvailFun)++newAvailCb :: AvailFun -> IO (Cb AvailFun)+newAvailCb = newCb availWrap+ data ObsConfig +-- TODO Use libremidi_midi_observer_configuration_init instance MallocPtr ObsConfig where   mallocPtr _ = mallocForeignPtrBytes0 #{size libremidi_observer_configuration} @@ -156,6 +171,7 @@  data MidiConfig +-- TODO Use libremidi_midi_configuration_init instance MallocPtr MidiConfig where   mallocPtr _ = mallocForeignPtrBytes0 #{size libremidi_midi_configuration} @@ -200,6 +216,24 @@  mcTimestamps :: Field MidiConfig TimestampMode mcTimestamps = newField #{offset libremidi_midi_configuration, timestamps}++foreign import ccall "libremidi/libremidi-c.h"+  libremidi_get_version :: IO CString++foreign import ccall "libremidi/libremidi-c.h"+  libremidi_midi1_available_apis :: Ptr Void -> FunPtr AvailFun -> IO ()++foreign import ccall "libremidi/libremidi-c.h"+  libremidi_midi2_available_apis :: Ptr Void -> FunPtr AvailFun -> IO ()++foreign import ccall "libremidi/libremidi-c.h"+  libremidi_api_identifier :: Api -> IO CString++foreign import ccall "libremidi/libremidi-c.h"+  libremidi_api_display_name :: Api -> IO CString++foreign import ccall "libremidi/libremidi-c.h"+  libremidi_get_compiled_api_by_identifier :: CString -> IO Api  foreign import ccall "libremidi/libremidi-c.h"   libremidi_midi_in_port_clone :: Ptr InPort -> Ptr (Ptr InPort) -> IO Err
src/Libremidi/Simple.hs view
@@ -111,3 +111,18 @@     let mc = def {LMA.mcPort = Just (LMA.MidiPortOut op')}     mc' <- liftIO (LMA.setMidiLogCb lf mc)     LMA.newOutHandle LMA.ApiUnspecified mc'++listAvailFun :: IORef (Seq LMA.Api) -> LMA.AvailFun+listAvailFun r = maybe (pure ()) (modifyIORef' r . flip (:|>))++listAvailApis1 :: IO (Seq LMA.Api)+listAvailApis1 = do+  r <- newIORef Empty+  LMA.availApis1 (listAvailFun r)+  readIORef r++listAvailApis2 :: IO (Seq LMA.Api)+listAvailApis2 = do+  r <- newIORef Empty+  LMA.availApis2 (listAvailFun r)+  readIORef r
test/Main.hs view
@@ -1,21 +1,34 @@+{-# LANGUAGE OverloadedStrings #-}+ module Main   ( main   ) where +import Libremidi.Api qualified as LMA+import Libremidi.Simple qualified as LMS import Test.Tasty (TestTree, defaultMain, testGroup)-import Test.Tasty.HUnit (testCase, (@?=))+import Test.Tasty.HUnit (assertBool, testCase, (@?=)) -testDummy :: TestTree-testDummy = testCase "dummy" $ do-  let actual = (1 + 1) :: Int-      expected = 2 :: Int-  actual @?= expected+testMetadata :: TestTree+testMetadata = testCase "metadata" $ do+  ver <- LMA.getVersion+  ver @?= "4.5.0"+  avail1 <- LMS.listAvailApis1+  assertBool "midi1 supports dummy" (LMA.ApiDummy `elem` avail1)+  avail2 <- LMS.listAvailApis2+  assertBool "midi2 supports dummy" (LMA.ApiDummy `elem` avail2)+  dummyIdent <- LMA.apiIdentifier LMA.ApiDummy+  dummyIdent @?= "dummy"+  dummyName <- LMA.apiDisplayName LMA.ApiDummy+  dummyName @?= "Dummy"+  dummyApi <- LMA.getCompiledApiByIdentifier "dummy"+  dummyApi @?= Just LMA.ApiDummy  main :: IO () main =   defaultMain $     testGroup       "Libremidi"-      [ testDummy+      [ testMetadata       ]
vendor/libremidi/api.hpp view
@@ -2,7 +2,6 @@ #include <libremidi/api-c.h> #include <libremidi/config.hpp> -#include <any> #include <string_view> #include <vector> @@ -30,9 +29,6 @@   API compiled for certain operating systems. */ LIBREMIDI_EXPORT std::vector<libremidi::API> available_ump_apis() noexcept;--LIBREMIDI_EXPORT-libremidi::API midi_api(const std::any& conf);  //! A static function to determine the current version. LIBREMIDI_EXPORT std::string_view get_version() noexcept;
vendor/libremidi/backends.hpp view
@@ -1,7 +1,6 @@ #pragma once #include <libremidi/config.hpp> -#include <any> #include <tuple>  #if !__has_include(<weak_libjack.h>) && !__has_include(<jack/jack.h>)@@ -202,10 +201,10 @@   midi2::for_backend(api, f); } -void for_input_configuration(auto f, std::any& api_conf)+void for_input_configuration(auto f, libremidi::input_api_configuration& api_conf) {   auto from_api = [&]<typename T>(T& /*backend*/) mutable {-    if (auto conf = std::any_cast<typename T::midi_in_configuration>(&api_conf))+    if (auto conf = std::get_if<typename T::midi_in_configuration>(&api_conf))     {       f(*conf);       return true;@@ -217,10 +216,10 @@   std::apply([&](auto&&... b) { return (from_api(b) || ...); }, midi2::available_backends); } -void for_output_configuration(auto f, std::any& api_conf)+void for_output_configuration(auto f, libremidi::output_api_configuration& api_conf) {   auto from_api = [&]<typename T>(T& /*backend*/) mutable {-    if (auto conf = std::any_cast<typename T::midi_out_configuration>(&api_conf))+    if (auto conf = std::get_if<typename T::midi_out_configuration>(&api_conf))     {       f(*conf);       return true;@@ -232,10 +231,10 @@   std::apply([&](auto&&... b) { return (from_api(b) || ...); }, midi2::available_backends); } -void for_observer_configuration(auto f, std::any& api_conf)+void for_observer_configuration(auto f, libremidi::observer_api_configuration& api_conf) {   auto from_api = [&]<typename T>(T& /*backend*/) mutable {-    if (auto conf = std::any_cast<typename T::midi_observer_configuration>(&api_conf))+    if (auto conf = std::get_if<typename T::midi_observer_configuration>(&api_conf))     {       f(*conf);       return true;
vendor/libremidi/backends/alsa_raw.hpp view
@@ -3,6 +3,7 @@ #include <libremidi/backends/alsa_raw/midi_out.hpp> #include <libremidi/backends/alsa_raw/observer.hpp> +#include <string_view> // Credits: greatly inspired from // https://ccrma.stanford.edu/~craig/articles/linuxmidi/alsa-1.0/alsarawmidiout.c // https://ccrma.stanford.edu/~craig/articles/linuxmidi/alsa-1.0/alsarawportlist.c@@ -19,8 +20,8 @@   using midi_out_configuration = alsa_raw_output_configuration;   using midi_observer_configuration = alsa_raw_observer_configuration;   static const constexpr auto API = libremidi::API::ALSA_RAW;-  static const constexpr auto name = "alsa_raw";-  static const constexpr auto display_name = "ALSA (raw)";+  static const constexpr std::string_view name = "alsa_raw";+  static const constexpr std::string_view display_name = "ALSA (raw)";    static inline bool available() noexcept   {
vendor/libremidi/backends/alsa_raw_ump.hpp view
@@ -5,6 +5,8 @@ #include <libremidi/backends/alsa_raw_ump/observer.hpp> #include <libremidi/backends/dummy.hpp> +#include <string_view>+ namespace libremidi::alsa_raw_ump { struct backend@@ -14,12 +16,11 @@   using midi_observer = observer_impl;   using midi_in_configuration = alsa_raw_ump::input_configuration;   using midi_out_configuration = alsa_raw_ump::output_configuration;-  struct midi_observer_configuration : alsa_raw_observer_configuration-  {-  };+  using midi_observer_configuration = alsa_raw_ump::observer_configuration;+   static const constexpr auto API = libremidi::API::ALSA_RAW_UMP;-  static const constexpr auto name = "alsa_raw_ump";-  static const constexpr auto display_name = "ALSA (raw UMP)";+  static const constexpr std::string_view name = "alsa_raw_ump";+  static const constexpr std::string_view display_name = "ALSA (raw UMP)";    static inline bool available() noexcept   {
vendor/libremidi/backends/alsa_raw_ump/config.hpp view
@@ -18,8 +18,7 @@   std::optional<chunking_parameters> chunking; }; -struct observer_configuration+struct observer_configuration : public alsa_raw_observer_configuration {-  std::chrono::milliseconds poll_period{100}; }; }
vendor/libremidi/backends/alsa_seq.hpp view
@@ -16,6 +16,8 @@ #include <libremidi/backends/alsa_seq/midi_out.hpp> #include <libremidi/backends/alsa_seq/observer.hpp> +#include <string_view>+ namespace libremidi::alsa_seq { @@ -29,8 +31,8 @@   using midi_out_configuration = alsa_seq::output_configuration;   using midi_observer_configuration = alsa_seq::observer_configuration;   static const constexpr auto API = libremidi::API::ALSA_SEQ;-  static const constexpr auto name = "alsa_seq";-  static const constexpr auto display_name = "ALSA (sequencer)";+  static const constexpr std::string_view name = "alsa_seq";+  static const constexpr std::string_view display_name = "ALSA (sequencer)";    static inline bool available() noexcept   {
vendor/libremidi/backends/alsa_seq/observer.hpp view
@@ -107,8 +107,8 @@     const auto tp = snd.seq.port_info_get_type(pinfo);     bool ok = this->configuration.track_any; -    static constexpr auto virtual_port-        = SND_SEQ_PORT_TYPE_SOFTWARE | SND_SEQ_PORT_TYPE_SYNTHESIZER;+    static constexpr auto virtual_port = SND_SEQ_PORT_TYPE_SOFTWARE | SND_SEQ_PORT_TYPE_SYNTHESIZER+                                         | SND_SEQ_PORT_TYPE_APPLICATION;      if ((tp & SND_SEQ_PORT_TYPE_HARDWARE) && this->configuration.track_hardware)       ok = true;
vendor/libremidi/backends/alsa_seq_ump.hpp view
@@ -5,6 +5,8 @@ #include <libremidi/backends/alsa_seq_ump/config.hpp> #include <libremidi/backends/alsa_seq_ump/midi_out.hpp> +#include <string_view>+ namespace libremidi { template <>@@ -50,8 +52,8 @@   using midi_out_configuration = alsa_seq_ump::output_configuration;   using midi_observer_configuration = alsa_seq_ump::observer_configuration;   static const constexpr auto API = libremidi::API::ALSA_SEQ_UMP;-  static const constexpr auto name = "alsa_seq_ump";-  static const constexpr auto display_name = "ALSA (sequencer, UMP)";+  static const constexpr std::string_view name = "alsa_seq_ump";+  static const constexpr std::string_view display_name = "ALSA (sequencer, UMP)";    static inline bool available() noexcept   {
vendor/libremidi/backends/coremidi.hpp view
@@ -3,6 +3,8 @@ #include <libremidi/backends/coremidi/midi_out.hpp> #include <libremidi/backends/coremidi/observer.hpp> +#include <string_view>+ namespace libremidi { struct core_backend@@ -14,8 +16,8 @@   using midi_out_configuration = coremidi_output_configuration;   using midi_observer_configuration = coremidi_observer_configuration;   static const constexpr auto API = libremidi::API::COREMIDI;-  static const constexpr auto name = "core";-  static const constexpr auto display_name = "CoreMIDI";+  static const constexpr std::string_view name = "core";+  static const constexpr std::string_view display_name = "CoreMIDI";    static constexpr inline bool available() noexcept { return true; } };
vendor/libremidi/backends/coremidi_ump.hpp view
@@ -3,6 +3,8 @@ #include <libremidi/backends/coremidi_ump/midi_out.hpp> #include <libremidi/backends/coremidi_ump/observer.hpp> +#include <string_view>+ namespace libremidi::coremidi_ump { struct backend@@ -14,8 +16,8 @@   using midi_out_configuration = coremidi_ump::output_configuration;   using midi_observer_configuration = coremidi_ump::observer_configuration;   static const constexpr auto API = libremidi::API::COREMIDI_UMP;-  static const constexpr auto name = "core_ump";-  static const constexpr auto display_name = "CoreMIDI UMP";+  static const constexpr std::string_view name = "core_ump";+  static const constexpr std::string_view display_name = "CoreMIDI UMP";    static constexpr inline bool available() noexcept { return true; /* todo? */ } };
vendor/libremidi/backends/dummy.hpp view
@@ -5,6 +5,8 @@ #include <libremidi/detail/midi_out.hpp> #include <libremidi/detail/observer.hpp> +#include <string_view>+ namespace libremidi { class observer_dummy : public observer_api@@ -23,11 +25,11 @@     , public error_handler { public:-  explicit midi_in_dummy(const input_configuration& configuration, std::any)+  explicit midi_in_dummy(const input_configuration& configuration, input_api_configuration)   {     libremidi_handle_warning(configuration, "This class provides no functionality.");   }-  explicit midi_in_dummy(const ump_input_configuration& configuration, std::any)+  explicit midi_in_dummy(const ump_input_configuration& configuration, input_api_configuration)   {     libremidi_handle_warning(configuration, "This class provides no functionality.");   }@@ -58,7 +60,7 @@     , public error_handler { public:-  explicit midi_out_dummy(const output_configuration& configuration, std::any)+  explicit midi_out_dummy(const output_configuration& configuration, output_api_configuration)   {     libremidi_handle_warning(configuration, "This class provides no functionality.");   }@@ -97,8 +99,8 @@   using midi_out_configuration = dummy_configuration;   using midi_observer_configuration = dummy_configuration;   static const constexpr auto API = libremidi::API::DUMMY;-  static const constexpr auto name = "dummy";-  static const constexpr auto display_name = "Dummy";+  static const constexpr std::string_view name = "dummy";+  static const constexpr std::string_view display_name = "Dummy";    static constexpr inline bool available() noexcept { return true; } };
vendor/libremidi/backends/emscripten.hpp view
@@ -7,6 +7,8 @@   #include <libremidi/backends/emscripten/midi_out.hpp>   #include <libremidi/backends/emscripten/observer.hpp> +  #include <string_view>+ namespace libremidi { @@ -19,8 +21,8 @@   using midi_out_configuration = emscripten_output_configuration;   using midi_observer_configuration = emscripten_observer_configuration;   static const constexpr auto API = libremidi::API::WEBMIDI;-  static const constexpr auto name = "webmidi";-  static const constexpr auto display_name = "WebMIDI";+  static const constexpr std::string_view name = "webmidi";+  static const constexpr std::string_view display_name = "WebMIDI";    static constexpr inline bool available() noexcept { return true; } };
vendor/libremidi/backends/jack.hpp view
@@ -3,6 +3,8 @@ #include <libremidi/backends/jack/midi_out.hpp> #include <libremidi/backends/jack/observer.hpp> +#include <string_view>+ //*********************************************************************// //  API: UNIX JACK //@@ -22,8 +24,8 @@   using midi_out_configuration = jack_output_configuration;   using midi_observer_configuration = jack_observer_configuration;   static const constexpr auto API = libremidi::API::JACK_MIDI;-  static const constexpr auto name = "jack";-  static const constexpr auto display_name = "JACK";+  static const constexpr std::string_view name = "jack";+  static const constexpr std::string_view display_name = "JACK";    static inline bool available() noexcept   {
vendor/libremidi/backends/keyboard.hpp view
@@ -2,6 +2,8 @@ #include <libremidi/backends/dummy.hpp> #include <libremidi/backends/keyboard/midi_in.hpp> +#include <string_view>+ namespace libremidi { struct kbd_backend@@ -13,8 +15,8 @@   using midi_out_configuration = dummy_configuration;   using midi_observer_configuration = dummy_configuration;   static const constexpr auto API = libremidi::API::KEYBOARD;-  static const constexpr auto name = "keyboard";-  static const constexpr auto display_name = "Computer keyboard";+  static const constexpr std::string_view name = "keyboard";+  static const constexpr std::string_view display_name = "Computer keyboard";    static inline bool available() noexcept { return true; } };
vendor/libremidi/backends/keyboard/config.hpp view
@@ -6,6 +6,128 @@  namespace libremidi {+enum kbd_event+{+  NOTE_0 = 0x0,         // C+  VEL_0 = NOTE_0 + 128, // Set velocity to 0+  OCT_0 = VEL_0 + 128,  // Set octave to 0+  OCTAVE_PLUS = OCT_0 + 128,+  OCTAVE_MINUS,+  VELOCITY_PLUS,+  VELOCITY_MINUS,+};++// Default map+//+// ,---,---,---,---,---,---,---,---,---,---,---,---,---,-------,+// | V0| V1| V2| V3| V4| V5| V6| V7| V8| V9|V10|V11|V12| <-    |+// |---'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-----|+// | ->| |   | C#| D#|   | F#| G#| A#|   | C#| D#|   | F#|     |+// |-----',--',--',--',--',--',--',--',--',--',--',--',--'|    |+// | Caps | C | D | E | F | G | A | B | C | D | E | F | G |    |+// |----,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'---'----|+// | -^ |   | O-| O+| V-| V+|   |   |   |   |   |   |   ----^  |+// |----'-,-',--'--,'---'---'---'---'---'---'-,-'---',--,------|+// | ctrl |  | alt |                          |altgr |  | ctrl |+// '------'  '-----'--------------------------'------'  '------'++// clang-format off++// actually based on macOS virtual codes as it seems+// impossible to get raw scan codes.+// https://eastmanreference.com/complete-list-of-applescript-key-codes+static inline const std::map<int, int>& scancode_map_macos(){+  static const std::map<int, int> ret{+  {  0, NOTE_0}, // C0+  { 13, NOTE_0 + 1},+  {  1, NOTE_0 + 2},+  { 14, NOTE_0 + 3},+  {  2, NOTE_0 + 4},+  {  3, NOTE_0 + 5},+  { 17, NOTE_0 + 6},+  {  5, NOTE_0 + 7},+  { 16, NOTE_0 + 8},+  {  4, NOTE_0 + 9},+  { 32, NOTE_0 + 10},+  { 38, NOTE_0 + 11},+  { 40, NOTE_0 + 12}, // C1+  { 31, NOTE_0 + 13},+  { 37, NOTE_0 + 14},+  { 35, NOTE_0 + 15},+  { 41, NOTE_0 + 16},+  { 39, NOTE_0 + 17},+  { 30, NOTE_0 + 18},+  { 42, NOTE_0 + 19},++  { 50, VEL_0 + int(0)},+  { 18, VEL_0 + int(1 * 127 / 12)},+  { 19, VEL_0 + int(2 * 127 / 12)},+  { 20, VEL_0 + int(3 * 127 / 12)},+  { 21, VEL_0 + int(4 * 127 / 12)},+  { 23, VEL_0 + int(5 * 127 / 12)},+  { 22, VEL_0 + int(6 * 127 / 12)},+  { 26, VEL_0 + int(7 * 127 / 12)},+  { 28, VEL_0 + int(8 * 127 / 12)},+  { 25, VEL_0 + int(9 * 127 / 12)},+  { 29, VEL_0 + int(10 * 127 / 12)},+  { 27, VEL_0 + int(11 * 127 / 12)},+  { 24, VEL_0 + int(127)},++  { 6, OCTAVE_MINUS },+  { 7, OCTAVE_PLUS },+  { 8, VELOCITY_MINUS },+  { 9, VELOCITY_PLUS},+  };+  return ret;+}++// Use: https://kbdlayout.info/KBDUSX/scancodes+// Also valid for windows+static inline const std::map<int, int>& scancode_map_linux() {+  static const std::map<int, int> ret{+  { 0x1E, NOTE_0}, // C0+  { 0x11, NOTE_0 + 1},+  { 0x1F, NOTE_0 + 2},+  { 0x12, NOTE_0 + 3},+  { 0x20, NOTE_0 + 4},+  { 0x21, NOTE_0 + 5},+  { 0x14, NOTE_0 + 6},+  { 0x22, NOTE_0 + 7},+  { 0x15, NOTE_0 + 8},+  { 0x23, NOTE_0 + 9},+  { 0x16, NOTE_0 + 10},+  { 0x24, NOTE_0 + 11},+  { 0x25, NOTE_0 + 12}, // C1+  { 0x18, NOTE_0 + 13},+  { 0x26, NOTE_0 + 14},+  { 0x19, NOTE_0 + 15},+  { 0x27, NOTE_0 + 16},+  { 0x28, NOTE_0 + 17},+  { 0x1B, NOTE_0 + 18},+  { 0x2B, NOTE_0 + 19},++  { 0x29, VEL_0 + int(0)},+  { 0x02, VEL_0 + int(1 * 127 / 12)},+  { 0x03, VEL_0 + int(2 * 127 / 12)},+  { 0x04, VEL_0 + int(3 * 127 / 12)},+  { 0x05, VEL_0 + int(4 * 127 / 12)},+  { 0x06, VEL_0 + int(5 * 127 / 12)},+  { 0x07, VEL_0 + int(6 * 127 / 12)},+  { 0x08, VEL_0 + int(7 * 127 / 12)},+  { 0x09, VEL_0 + int(8 * 127 / 12)},+  { 0x0A, VEL_0 + int(9 * 127 / 12)},+  { 0x0B, VEL_0 + int(10 * 127 / 12)},+  { 0x0C, VEL_0 + int(11 * 127 / 12)},+  { 0x0D, VEL_0 + int(127)},++  { 0x2C, OCTAVE_MINUS },+  { 0x2D, OCTAVE_PLUS },+  { 0x2E, VELOCITY_MINUS },+  { 0x2F, VELOCITY_PLUS},+  };+  return ret;+}+// clang-format on /**  * Used to set up keyboard input.  * Your app should pass a function that will give you a callback@@ -13,80 +135,20 @@  */ struct kbd_input_configuration {+  // Note that on Linux with X11 scancodes should be offset by 8 (an X11 legacy quirk)+  // ex.: pass QKeyEvent::nativeScanCode() - 8 to this API   using scancode_callback = std::function<void(int)>;+   // First argument is on key press, second on key release   std::function<void(scancode_callback, scancode_callback)> set_input_scancode_callbacks-      = [](scancode_callback, scancode_callback) {};--  enum kbd_event-  {-    NOTE_0 = 0x0,         // C-    VEL_0 = NOTE_0 + 128, // Set velocity to 0-    OCT_0 = VEL_0 + 128,  // Set octave to 0-    OCTAVE_PLUS = OCT_0 + 128,-    OCTAVE_MINUS,-    VELOCITY_PLUS,-    VELOCITY_MINUS,-  };--  // Default map-  //-  // ,---,---,---,---,---,---,---,---,---,---,---,---,---,-------,-  // | V0| V1| V2| V3| V4| V5| V6| V7| V8| V9|V10|V11|V12| <-    |-  // |---'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-----|-  // | ->| |   | C#| D#|   | F#| G#| A#|   | C#| D#|   | F#|     |-  // |-----',--',--',--',--',--',--',--',--',--',--',--',--'|    |-  // | Caps | C | D | E | F | G | A | B | C | D | E | F | G |    |-  // |----,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'---'----|-  // | -^ |   | O-| O+| V-| V+|   |   |   |   |   |   |   ----^  |-  // |----'-,-',--'--,'---'---'---'---'---'---'-,-'---',--,------|-  // | ctrl |  | alt |                          |altgr |  | ctrl |-  // '------'  '-----'--------------------------'------'  '------'--  // clang-format off-  // Use: https://kbdlayout.info/KBDUSX/scancodes-  std::map<int, int> scancode_map{-      { 0x1E, NOTE_0}, // C0-      { 0x11, NOTE_0 + 1},-      { 0x1F, NOTE_0 + 2},-      { 0x12, NOTE_0 + 3},-      { 0x20, NOTE_0 + 4},-      { 0x21, NOTE_0 + 5},-      { 0x14, NOTE_0 + 6},-      { 0x22, NOTE_0 + 7},-      { 0x15, NOTE_0 + 8},-      { 0x23, NOTE_0 + 9},-      { 0x16, NOTE_0 + 10},-      { 0x24, NOTE_0 + 11},-      { 0x25, NOTE_0 + 12}, // C1-      { 0x18, NOTE_0 + 13}, -      { 0x26, NOTE_0 + 14}, -      { 0x19, NOTE_0 + 15},-      { 0x27, NOTE_0 + 16},-      { 0x28, NOTE_0 + 17},-      { 0x1B, NOTE_0 + 18},-      { 0x2B, NOTE_0 + 19},--      { 0x29, VEL_0 + int(0)},-      { 0x02, VEL_0 + int(1 * 127 / 12)},-      { 0x03, VEL_0 + int(2 * 127 / 12)},-      { 0x04, VEL_0 + int(3 * 127 / 12)},-      { 0x05, VEL_0 + int(4 * 127 / 12)},-      { 0x06, VEL_0 + int(5 * 127 / 12)},-      { 0x07, VEL_0 + int(6 * 127 / 12)},-      { 0x08, VEL_0 + int(7 * 127 / 12)},-      { 0x09, VEL_0 + int(8 * 127 / 12)},-      { 0x0A, VEL_0 + int(9 * 127 / 12)},-      { 0x0B, VEL_0 + int(10 * 127 / 12)},-      { 0x0C, VEL_0 + int(11 * 127 / 12)},-      { 0x0D, VEL_0 + int(127)},+      = [](scancode_callback, scancode_callback) { }; -      { 0x2C, OCTAVE_MINUS },-      { 0x2D, OCTAVE_PLUS },-      { 0x2E, VELOCITY_MINUS },-      { 0x2F, VELOCITY_PLUS}, -  };-  // clang-format on+  std::map<int, int> scancode_map+#if defined(__APPLE__)+      = scancode_map_macos()+#else+      = scancode_map_linux()+#endif+      ; };- }
vendor/libremidi/backends/keyboard/midi_in.hpp view
@@ -45,7 +45,7 @@    void on_keypress(int scancode)   {-    using kevent = kbd_input_configuration::kbd_event;+    using kevent = libremidi::kbd_event;      auto it = configuration.scancode_map.find(scancode);     if (it == configuration.scancode_map.end())@@ -88,7 +88,7 @@    void on_keyrelease(int scancode)   {-    using kevent = kbd_input_configuration::kbd_event;+    using kevent = libremidi::kbd_event;      auto it = configuration.scancode_map.find(scancode);     if (it == configuration.scancode_map.end())
vendor/libremidi/backends/network.hpp view
@@ -5,6 +5,8 @@ #include <libremidi/backends/net/midi_out.hpp> #include <libremidi/backends/net/observer.hpp> +#include <string_view>+ namespace libremidi::net { struct backend@@ -16,8 +18,8 @@   using midi_out_configuration = libremidi::net::dgram_output_configuration;   using midi_observer_configuration = libremidi::net::net_observer_configuration;   static const constexpr auto API = libremidi::API::NETWORK;-  static const constexpr auto name = "network";-  static const constexpr auto display_name = "Network";+  static const constexpr std::string_view name = "network";+  static const constexpr std::string_view display_name = "Network";    static inline bool available() noexcept { return true; } };
vendor/libremidi/backends/network_ump.hpp view
@@ -4,6 +4,8 @@ #include <libremidi/backends/net/midi_out.hpp> #include <libremidi/backends/net/observer.hpp> +#include <string_view>+ namespace libremidi::net_ump { struct backend@@ -15,8 +17,8 @@   using midi_out_configuration = libremidi::net_ump::dgram_output_configuration;   using midi_observer_configuration = libremidi::net_ump::net_observer_configuration;   static const constexpr auto API = libremidi::API::NETWORK_UMP;-  static const constexpr auto name = "network (UMP)";-  static const constexpr auto display_name = "Network (UMP)";+  static const constexpr std::string_view name = "network (UMP)";+  static const constexpr std::string_view display_name = "Network (UMP)";    static inline bool available() noexcept { return true; } };
vendor/libremidi/backends/pipewire.hpp view
@@ -7,6 +7,8 @@ #include <libremidi/backends/pipewire/midi_out.hpp> #include <libremidi/backends/pipewire/observer.hpp> +#include <string_view>+ namespace libremidi::pipewire { struct backend@@ -18,8 +20,8 @@   using midi_out_configuration = pipewire_output_configuration;   using midi_observer_configuration = pipewire_observer_configuration;   static const constexpr auto API = libremidi::API::PIPEWIRE;-  static const constexpr auto name = "pipewire";-  static const constexpr auto display_name = "PipeWire";+  static const constexpr std::string_view name = "pipewire";+  static const constexpr std::string_view display_name = "PipeWire";    static inline bool available() noexcept   {
vendor/libremidi/backends/winmidi.hpp view
@@ -3,6 +3,8 @@ #include <libremidi/backends/winmidi/midi_out.hpp> #include <libremidi/backends/winmidi/observer.hpp> +#include <string_view>+ namespace libremidi::winmidi { struct backend@@ -14,8 +16,8 @@   using midi_out_configuration = winmidi::output_configuration;   using midi_observer_configuration = winmidi::observer_configuration;   static const constexpr auto API = libremidi::API::WINDOWS_MIDI_SERVICES;-  static const constexpr auto name = "winmidi";-  static const constexpr auto display_name = "Windows MIDI Services";+  static const constexpr std::string_view name = "winmidi";+  static const constexpr std::string_view display_name = "Windows MIDI Services";    static constexpr inline bool available() noexcept { return true; } };
vendor/libremidi/backends/winmm.hpp view
@@ -3,6 +3,8 @@ #include <libremidi/backends/winmm/midi_out.hpp> #include <libremidi/backends/winmm/observer.hpp> +#include <string_view>+ // Default for Windows is to add an identifier to the port names; this // flag can be defined (e.g. in your project file) to disable this behaviour. // #define LIBREMIDI_DO_NOT_ENSURE_UNIQUE_PORTNAMES@@ -28,8 +30,8 @@   using midi_out_configuration = winmm_output_configuration;   using midi_observer_configuration = winmm_observer_configuration;   static const constexpr auto API = libremidi::API::WINDOWS_MM;-  static const constexpr auto name = "winmm";-  static const constexpr auto display_name = "Windows Multimedia";+  static const constexpr std::string_view name = "winmm";+  static const constexpr std::string_view display_name = "Windows Multimedia";    static constexpr inline bool available() noexcept { return true; } };
vendor/libremidi/backends/winuwp.hpp view
@@ -3,6 +3,8 @@ #include <libremidi/backends/winuwp/midi_out.hpp> #include <libremidi/backends/winuwp/observer.hpp> +#include <string_view>+ namespace libremidi { struct winuwp_backend@@ -14,8 +16,8 @@   using midi_out_configuration = winuwp_output_configuration;   using midi_observer_configuration = winuwp_observer_configuration;   static const constexpr auto API = libremidi::API::WINDOWS_UWP;-  static const constexpr auto name = "winuwp";-  static const constexpr auto display_name = "Windows UWP";+  static const constexpr std::string_view name = "winuwp";+  static const constexpr std::string_view display_name = "Windows UWP";    static constexpr inline bool available() noexcept { return true; } };
vendor/libremidi/configurations.hpp view
@@ -1,5 +1,6 @@ #pragma once +#include <libremidi/api.hpp> #include <libremidi/backends/alsa_raw/config.hpp> #include <libremidi/backends/alsa_raw_ump/config.hpp> #include <libremidi/backends/alsa_seq/config.hpp>@@ -14,11 +15,51 @@ #include <libremidi/backends/winmidi/config.hpp> #include <libremidi/backends/winmm/config.hpp> #include <libremidi/backends/winuwp/config.hpp>+#include <libremidi/config.hpp> +#include <variant> namespace libremidi {-+struct unspecified_configuration+{+}; struct dummy_configuration { };++using input_api_configuration = std::variant<+    unspecified_configuration, dummy_configuration, alsa_raw_input_configuration,+    alsa_raw_ump::input_configuration, alsa_seq::input_configuration,+    alsa_seq_ump::input_configuration, coremidi_input_configuration,+    coremidi_ump::input_configuration, emscripten_input_configuration, jack_input_configuration,+    kbd_input_configuration, libremidi::net::dgram_input_configuration,+    libremidi::net_ump::dgram_input_configuration, pipewire_input_configuration,+    winmidi::input_configuration, winmm_input_configuration, winuwp_input_configuration,+    libremidi::API>;++using output_api_configuration = std::variant<+    unspecified_configuration, dummy_configuration, alsa_raw_output_configuration,+    alsa_raw_ump::output_configuration, alsa_seq::output_configuration,+    alsa_seq_ump::output_configuration, coremidi_output_configuration,+    coremidi_ump::output_configuration, emscripten_output_configuration, jack_output_configuration,+    libremidi::net::dgram_output_configuration, libremidi::net_ump::dgram_output_configuration,+    pipewire_output_configuration, winmidi::output_configuration, winmm_output_configuration,+    winuwp_output_configuration, libremidi::API>;++using observer_api_configuration = std::variant<+    unspecified_configuration, dummy_configuration, alsa_raw_observer_configuration,+    alsa_raw_ump::observer_configuration, alsa_seq::observer_configuration,+    alsa_seq_ump::observer_configuration, coremidi_observer_configuration,+    coremidi_ump::observer_configuration, emscripten_observer_configuration,+    jack_observer_configuration, libremidi::net::dgram_observer_configuration,+    libremidi::net_ump::dgram_observer_configuration, pipewire_observer_configuration,+    winmidi::observer_configuration, winmm_observer_configuration, winuwp_observer_configuration,+    libremidi::API>;++LIBREMIDI_EXPORT+libremidi::API midi_api(const input_api_configuration& conf);+LIBREMIDI_EXPORT+libremidi::API midi_api(const output_api_configuration& conf);+LIBREMIDI_EXPORT+libremidi::API midi_api(const observer_api_configuration& conf); }
vendor/libremidi/defaults.hpp view
@@ -1,11 +1,11 @@ #pragma once #include <libremidi/api.hpp> #include <libremidi/config.hpp>+#include <libremidi/configurations.hpp> #include <libremidi/input_configuration.hpp> #include <libremidi/observer_configuration.hpp> #include <libremidi/output_configuration.hpp> -#include <any> #include <optional>  namespace libremidi@@ -16,22 +16,22 @@  //! Get the default midi in configuration object for a given API LIBREMIDI_EXPORT-std::any midi_in_configuration_for(libremidi::API);+input_api_configuration midi_in_configuration_for(libremidi::API);  //! Get the default midi out configuration object for a given API LIBREMIDI_EXPORT-std::any midi_out_configuration_for(libremidi::API);+output_api_configuration midi_out_configuration_for(libremidi::API);  //! Get the default observer configuration object for a given API LIBREMIDI_EXPORT-std::any observer_configuration_for(libremidi::API);+observer_api_configuration observer_configuration_for(libremidi::API);  //! Get a matching midi in configuration object for a given observer instance. LIBREMIDI_EXPORT-std::any midi_in_configuration_for(const libremidi::observer&);+input_api_configuration midi_in_configuration_for(const libremidi::observer&); //! Get a matching midi out configuration object for a given observer instance. LIBREMIDI_EXPORT-std::any midi_out_configuration_for(const libremidi::observer&);+output_api_configuration midi_out_configuration_for(const libremidi::observer&);  //! Get the default port for midi input (if any) in a given API. //! Note that this will only return a hardware / physical port.@@ -47,15 +47,15 @@ { //! Get a default configuration for creating a MIDI 1 input LIBREMIDI_EXPORT-std::any in_default_configuration();+input_api_configuration in_default_configuration();  //! Get a default configuration for creating a MIDI 1 output LIBREMIDI_EXPORT-std::any out_default_configuration();+output_api_configuration out_default_configuration();  //! Get a default configuration for creating a MIDI 1 observer LIBREMIDI_EXPORT-std::any observer_default_configuration();+observer_api_configuration observer_default_configuration();  //! Get a default MIDI 1 input port for the default API of the system inline std::optional<input_port> in_default_port() noexcept@@ -74,15 +74,15 @@ { //! Get a default configuration for creating a MIDI 2 input LIBREMIDI_EXPORT-std::any in_default_configuration();+input_api_configuration in_default_configuration();  //! Get a default configuration for creating a MIDI 2 output LIBREMIDI_EXPORT-std::any out_default_configuration();+output_api_configuration out_default_configuration();  //! Get a default configuration for creating a MIDI 2 observer LIBREMIDI_EXPORT-std::any observer_default_configuration();+observer_api_configuration observer_default_configuration();  //! Get a default MIDI 2 input port for the default API of the system inline std::optional<input_port> in_default_port() noexcept
vendor/libremidi/libremidi-c.cpp view
@@ -44,14 +44,14 @@   return LIBREMIDI_VERSION; } -void libremidi_available_midi1_apis(void* ctx, void (*cb)(void* ctx, libremidi_api))+void libremidi_midi1_available_apis(void* ctx, void (*cb)(void* ctx, libremidi_api)) {   if (!cb)     return;   libremidi::midi1::for_all_backends([=](auto b) { cb(ctx, b.API); }); } -void libremidi_available_midi2_apis(void* ctx, void (*cb)(void* ctx, libremidi_api))+void libremidi_midi2_available_apis(void* ctx, void (*cb)(void* ctx, libremidi_api)) {   if (!cb)     return;
vendor/libremidi/libremidi.cpp view
@@ -53,14 +53,13 @@   midi2::for_all_backends([&](auto b) { apis.push_back(b.API); });   return apis; }+ LIBREMIDI_INLINE-libremidi::API midi_api(const std::any& conf)+libremidi::API midi_api(const input_api_configuration& conf) {   libremidi::API ret = libremidi::API::UNSPECIFIED;   midi_any::for_all_backends([&]<typename T>(T) {-    if (std::any_cast<typename T::midi_in_configuration>(&conf)-        || std::any_cast<typename T::midi_out_configuration>(&conf)-        || std::any_cast<typename T::midi_observer_configuration>(&conf))+    if (std::get_if<typename T::midi_in_configuration>(&conf))     {       ret = T::API;     }@@ -68,9 +67,34 @@   return ret; } LIBREMIDI_INLINE-std::any midi_in_configuration_for(libremidi::API api)+libremidi::API midi_api(const output_api_configuration& conf) {-  std::any ret;+  libremidi::API ret = libremidi::API::UNSPECIFIED;+  midi_any::for_all_backends([&]<typename T>(T) {+    if (std::get_if<typename T::midi_out_configuration>(&conf))+    {+      ret = T::API;+    }+  });+  return ret;+}+LIBREMIDI_INLINE+libremidi::API midi_api(const observer_api_configuration& conf)+{+  libremidi::API ret = libremidi::API::UNSPECIFIED;+  midi_any::for_all_backends([&]<typename T>(T) {+    if (std::get_if<typename T::midi_observer_configuration>(&conf))+    {+      ret = T::API;+    }+  });+  return ret;+}++LIBREMIDI_INLINE+input_api_configuration midi_in_configuration_for(libremidi::API api)+{+  input_api_configuration ret;   midi_any::for_backend(api, [&]<typename T>(T) {     using conf_type = typename T::midi_in_configuration;     ret = conf_type{};@@ -79,9 +103,9 @@ }  LIBREMIDI_INLINE-std::any midi_out_configuration_for(libremidi::API api)+output_api_configuration midi_out_configuration_for(libremidi::API api) {-  std::any ret;+  output_api_configuration ret;   midi_any::for_backend(api, [&]<typename T>(T) {     using conf_type = typename T::midi_out_configuration;     ret = conf_type{};@@ -90,9 +114,9 @@ }  LIBREMIDI_INLINE-std::any observer_configuration_for(libremidi::API api)+observer_api_configuration observer_configuration_for(libremidi::API api) {-  std::any ret;+  observer_api_configuration ret;   midi_any::for_backend(api, [&]<typename T>(T) {     using conf_type = typename T::midi_observer_configuration;     ret = conf_type{};@@ -101,13 +125,13 @@ }  LIBREMIDI_INLINE-std::any midi_in_configuration_for(const libremidi::observer& obs)+input_api_configuration midi_in_configuration_for(const libremidi::observer& obs) {   return midi_in_configuration_for(obs.get_current_api()); }  LIBREMIDI_INLINE-std::any midi_out_configuration_for(const libremidi::observer& obs)+output_api_configuration midi_out_configuration_for(const libremidi::observer& obs) {   // FIXME reuse context when meaningful, e.g. ALSA, JACK...   return midi_out_configuration_for(obs.get_current_api());@@ -144,19 +168,19 @@ namespace midi1 { LIBREMIDI_INLINE-std::any in_default_configuration()+input_api_configuration in_default_configuration() {   return midi_in_configuration_for(default_api()); }  LIBREMIDI_INLINE-std::any out_default_configuration()+output_api_configuration out_default_configuration() {   return midi_out_configuration_for(default_api()); }  LIBREMIDI_INLINE-std::any observer_default_configuration()+observer_api_configuration observer_default_configuration() {   return observer_configuration_for(default_api()); }@@ -165,19 +189,19 @@ namespace midi2 { LIBREMIDI_INLINE-std::any in_default_configuration()+input_api_configuration in_default_configuration() {   return midi_in_configuration_for(default_api()); }  LIBREMIDI_INLINE-std::any out_default_configuration()+output_api_configuration out_default_configuration() {   return midi_out_configuration_for(default_api()); }  LIBREMIDI_INLINE-std::any observer_default_configuration()+observer_api_configuration observer_default_configuration() {   return observer_configuration_for(default_api()); }
vendor/libremidi/libremidi.hpp view
@@ -58,6 +58,7 @@ */  #include <libremidi/api.hpp>+#include <libremidi/configurations.hpp> #include <libremidi/defaults.hpp> #include <libremidi/input_configuration.hpp> #include <libremidi/message.hpp>@@ -68,7 +69,6 @@   #include <midi/sysex.h>   #include <midi/universal_packet.h> #endif-#include <any>  namespace libremidi {@@ -84,7 +84,7 @@   //!   such as jack_observer_configuration, winmm_observer_configuration, etc...   //! * if no callbacks are passed, no secondary thread will be created unless absolutely necessary   explicit observer(const observer_configuration& conf = {}) noexcept;-  explicit observer(observer_configuration conf, std::any api_conf);+  explicit observer(observer_configuration conf, observer_api_configuration api_conf);   observer(const observer&) = delete;   observer(observer&& other) noexcept;   observer& operator=(const observer&) = delete;@@ -111,7 +111,7 @@   //! Construct a midi_in object with a configuration object for a specific MIDI 1 back-end   //! see configuration.hpp for the available configuration types.   //! An exception will be thrown if the requested back-end cannot be opened.-  explicit midi_in(input_configuration conf, std::any api_conf);+  explicit midi_in(input_configuration conf, input_api_configuration api_conf);    //! Construct a midi_in object with the default MIDI 2 back-end for the platform   explicit midi_in(ump_input_configuration conf) noexcept;@@ -119,7 +119,7 @@   //! Construct a midi_in object with a configuration object for a specific MIDI 2 back-end   //! see configuration.hpp for the available configuration types.   //! An exception will be thrown if the requested back-end cannot be opened.-  explicit midi_in(ump_input_configuration conf, std::any api_conf);+  explicit midi_in(ump_input_configuration conf, input_api_configuration api_conf);    midi_in(const midi_in&) = delete;   midi_in(midi_in&& other) noexcept;@@ -170,7 +170,7 @@   //! Construct a midi_out object with a configuration object for a specific back-end   //! see configuration.hpp for the available configuration types.   //! An exception will be thrown if the requested back-end cannot be opened.-  explicit midi_out(output_configuration conf, std::any api_conf);+  explicit midi_out(output_configuration conf, output_api_configuration api_conf);    midi_out(const midi_out&) = delete;   midi_out(midi_out&& other) noexcept;
vendor/libremidi/midi_in.cpp view
@@ -61,14 +61,14 @@ }  static LIBREMIDI_INLINE std::unique_ptr<midi_in_api>-make_midi_in(auto base_conf, std::any api_conf, auto backends)+make_midi_in(auto base_conf, input_api_configuration api_conf, auto backends) {   std::unique_ptr<midi_in_api> ptr;    assert(base_conf.on_message || base_conf.on_raw_data);    auto from_api = [&]<typename T>(T& /*backend*/) mutable {-    if (auto conf = std::any_cast<typename T::midi_in_configuration>(&api_conf))+    if (auto conf = std::get_if<typename T::midi_in_configuration>(&api_conf))     {       ptr = libremidi::make<typename T::midi_in>(std::move(base_conf), std::move(*conf));       return true;@@ -117,8 +117,9 @@   return std::make_unique<midi_in_dummy>(input_configuration{}, dummy_configuration{}); } -static LIBREMIDI_INLINE std::unique_ptr<midi_in_api>-make_midi1_in(const input_configuration& base_conf, const std::any& api_conf, libremidi::API api)+static LIBREMIDI_INLINE std::unique_ptr<midi_in_api> make_midi1_in(+    const input_configuration& base_conf, const input_api_configuration& api_conf,+    libremidi::API api) {   if (libremidi::is_midi1(api))   {@@ -133,13 +134,13 @@ }  static LIBREMIDI_INLINE std::unique_ptr<midi_in_api>-make_midi1_in(const input_configuration& base_conf, const std::any& api_conf)+make_midi1_in(const input_configuration& base_conf, const input_api_configuration& api_conf) {-  if (!api_conf.has_value())+  if (std::get_if<unspecified_configuration>(&api_conf))   {     return make_midi1_in(base_conf);   }-  else if (auto api_p = std::any_cast<libremidi::API>(&api_conf))+  else if (auto api_p = std::get_if<libremidi::API>(&api_conf))   {     if (*api_p == libremidi::API::UNSPECIFIED)     {@@ -166,7 +167,7 @@ }  LIBREMIDI_INLINE-midi_in::midi_in(input_configuration base_conf, std::any api_conf)+midi_in::midi_in(input_configuration base_conf, input_api_configuration api_conf)     : impl_{make_midi1_in(base_conf, api_conf)} {   if (!impl_)@@ -214,7 +215,8 @@ }  static LIBREMIDI_INLINE std::unique_ptr<midi_in_api> make_midi2_in(-    const ump_input_configuration& base_conf, const std::any& api_conf, libremidi::API api)+    const ump_input_configuration& base_conf, const input_api_configuration& api_conf,+    libremidi::API api) {   if (is_midi2(api))   {@@ -230,13 +232,13 @@ }  static LIBREMIDI_INLINE std::unique_ptr<midi_in_api>-make_midi2_in(const ump_input_configuration& base_conf, const std::any& api_conf)+make_midi2_in(const ump_input_configuration& base_conf, const input_api_configuration& api_conf) {-  if (!api_conf.has_value())+  if (std::get_if<unspecified_configuration>(&api_conf))   {     return make_midi2_in(base_conf);   }-  else if (auto api_p = std::any_cast<libremidi::API>(&api_conf))+  else if (auto api_p = std::get_if<libremidi::API>(&api_conf))   {     if (*api_p == libremidi::API::UNSPECIFIED)     {@@ -263,7 +265,7 @@ }  LIBREMIDI_INLINE-midi_in::midi_in(ump_input_configuration base_conf, std::any api_conf)+midi_in::midi_in(ump_input_configuration base_conf, input_api_configuration api_conf)     : impl_{make_midi2_in(base_conf, api_conf)} {   if (!impl_)
vendor/libremidi/midi_out.cpp view
@@ -11,11 +11,11 @@ namespace libremidi { static LIBREMIDI_INLINE std::unique_ptr<midi_out_api>-make_midi_out_impl(auto base_conf, std::any api_conf)+make_midi_out_impl(auto base_conf, output_api_configuration api_conf) {   std::unique_ptr<midi_out_api> ptr;   auto from_api = [&]<typename T>(T& /*backend*/) mutable {-    if (auto conf = std::any_cast<typename T::midi_out_configuration>(&api_conf))+    if (auto conf = std::get_if<typename T::midi_out_configuration>(&api_conf))     {       ptr = libremidi::make<typename T::midi_out>(std::move(base_conf), std::move(*conf));       return true;@@ -58,13 +58,13 @@ }  static LIBREMIDI_INLINE std::unique_ptr<midi_out_api>-make_midi_out(const output_configuration& base_conf, const std::any& api_conf)+make_midi_out(const output_configuration& base_conf, const output_api_configuration& api_conf) {-  if (!api_conf.has_value())+  if (std::get_if<unspecified_configuration>(&api_conf))   {     return make_midi_out(base_conf);   }-  else if (auto api_p = std::any_cast<libremidi::API>(&api_conf))+  else if (auto api_p = std::get_if<libremidi::API>(&api_conf))   {     if (*api_p == libremidi::API::UNSPECIFIED)     {@@ -90,7 +90,7 @@ }  LIBREMIDI_INLINE-midi_out::midi_out(output_configuration base_conf, std::any api_conf)+midi_out::midi_out(output_configuration base_conf, output_api_configuration api_conf)     : impl_{make_midi_out(base_conf, api_conf)} {   if (!impl_)
vendor/libremidi/observer.cpp view
@@ -37,11 +37,11 @@   return std::make_unique<observer_dummy>(observer_configuration{}, dummy_configuration{}); } -LIBREMIDI_INLINE auto make_observer_impl(auto base_conf, std::any api_conf)+LIBREMIDI_INLINE auto make_observer_impl(auto base_conf, observer_api_configuration api_conf) {   std::unique_ptr<observer_api> ptr;   auto from_api = [&]<typename T>(T& /*backend*/) mutable {-    if (auto conf = std::any_cast<typename T::midi_observer_configuration>(&api_conf))+    if (auto conf = std::get_if<typename T::midi_observer_configuration>(&api_conf))     {       ptr = libremidi::make<typename T::midi_observer>(std::move(base_conf), std::move(*conf));       return true;@@ -53,13 +53,14 @@   return ptr; } -LIBREMIDI_INLINE std::unique_ptr<observer_api> make_observer(auto base_conf, std::any api_conf)+LIBREMIDI_INLINE std::unique_ptr<observer_api>+make_observer(auto base_conf, observer_api_configuration api_conf) {-  if (!api_conf.has_value())+  if (std::get_if<unspecified_configuration>(&api_conf))   {     return make_observer(base_conf);   }-  else if (auto api_p = std::any_cast<libremidi::API>(&api_conf))+  else if (auto api_p = std::get_if<libremidi::API>(&api_conf))   {     if (*api_p == libremidi::API::UNSPECIFIED)     {@@ -84,7 +85,8 @@ { } -LIBREMIDI_INLINE observer::observer(observer_configuration base_conf, std::any api_conf)+LIBREMIDI_INLINE+observer::observer(observer_configuration base_conf, observer_api_configuration api_conf)     : impl_{make_observer(base_conf, api_conf)} {   if (!impl_)
vendor/libremidi/shared_context.hpp view
@@ -1,8 +1,6 @@ #pragma once #include <libremidi/api.hpp>-#include <libremidi/config.hpp>--#include <any>+#include <libremidi/configurations.hpp>  namespace libremidi {@@ -24,7 +22,9 @@ struct shared_configurations {   std::shared_ptr<shared_context> context;-  std::any observer, in, out;+  observer_api_configuration observer;+  input_api_configuration in;+  output_api_configuration out; };  LIBREMIDI_EXPORT