libremidi 0.4.1 → 0.4.2
raw patch · 37 files changed
+470/−203 lines, 37 files
Files
- libremidi.cabal +1/−1
- src/Libremidi/Api.hs +42/−0
- src/Libremidi/Common.hs +10/−2
- src/Libremidi/Foreign.hsc +34/−0
- src/Libremidi/Simple.hs +15/−0
- test/Main.hs +20/−7
- vendor/libremidi/api.hpp +0/−4
- vendor/libremidi/backends.hpp +6/−7
- vendor/libremidi/backends/alsa_raw.hpp +3/−2
- vendor/libremidi/backends/alsa_raw_ump.hpp +6/−5
- vendor/libremidi/backends/alsa_raw_ump/config.hpp +1/−2
- vendor/libremidi/backends/alsa_seq.hpp +4/−2
- vendor/libremidi/backends/alsa_seq/observer.hpp +2/−2
- vendor/libremidi/backends/alsa_seq_ump.hpp +4/−2
- vendor/libremidi/backends/coremidi.hpp +4/−2
- vendor/libremidi/backends/coremidi_ump.hpp +4/−2
- vendor/libremidi/backends/dummy.hpp +7/−5
- vendor/libremidi/backends/emscripten.hpp +4/−2
- vendor/libremidi/backends/jack.hpp +4/−2
- vendor/libremidi/backends/keyboard.hpp +4/−2
- vendor/libremidi/backends/keyboard/config.hpp +133/−71
- vendor/libremidi/backends/keyboard/midi_in.hpp +2/−2
- vendor/libremidi/backends/network.hpp +4/−2
- vendor/libremidi/backends/network_ump.hpp +4/−2
- vendor/libremidi/backends/pipewire.hpp +4/−2
- vendor/libremidi/backends/winmidi.hpp +4/−2
- vendor/libremidi/backends/winmm.hpp +4/−2
- vendor/libremidi/backends/winuwp.hpp +4/−2
- vendor/libremidi/configurations.hpp +42/−1
- vendor/libremidi/defaults.hpp +12/−12
- vendor/libremidi/libremidi-c.cpp +2/−2
- vendor/libremidi/libremidi.cpp +42/−18
- vendor/libremidi/libremidi.hpp +5/−5
- vendor/libremidi/midi_in.cpp +15/−13
- vendor/libremidi/midi_out.cpp +6/−6
- vendor/libremidi/observer.cpp +8/−6
- vendor/libremidi/shared_context.hpp +4/−4
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_)
@@ -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