Skip to main content

A modern C++ MIDI 1 / MIDI 2 real-time & file I/O library. Supports Windows, macOS, Linux and WebMIDI.

Project description

libremidi

Build status

Packaging status

libremidi is a cross-platform C++20 library for real-time and MIDI file input and output.

This is a fork / rewrite based on two libraries:

Additionnally, for MIDI 2 parsing support we use cmidi2!

Read the documentation here.

Citation

If you use this work as part of academic research, please kindly cite the paper:

@inproceedings{celerier2024libremidi,
  title={libremidi: a cross-platform library for real-time MIDI 1 and 2},
  author={Celerier, Jean-Micha{\"e}l},
  booktitle={Proceedings of the Sound and Music Computing Conference (SMC)},
  year={2024},
  address={Porto, Portugal}
}

Changelog

Since v5.4

  • ALSA: observation will now slightly be delayed as otherwise udev fields are sometimes not populated yet.
  • Port the Android backend from RtMidi, developed by @YellowLabrador.
  • C++: add initial C++ modules support: import libremidi;. So far compilers other than Clang 20+ crash. Enable with -DLIBREMIDI_LIBRARY_MODE=MODULE. Note that one cannot mix a module-based and a non-module based API. An example is provided in examples/modules.cpp
  • Add a utility libremidi::set_client_name / client_name function to simplify construction of an API object with a custom client name.
  • Many improvements to MIDI 1 <-> MIDI 2 conversion, every MIDI 1 message is supported now.
  • Port information: add as much metadata as we can get from the host API.
  • Port information: remove sorting and comparison as there's no generally correct way to compare two port_information / input_port / output_port objects. Multiple ways of doing this comparison depending on the use case have been provided as examples in <libremidi/port_comparison.hpp>.
  • Port information: added a heuristics-based libremidi::find_closest_port(query, existing_ports) utility function which tries to lookup the most likely candidate for a MIDI port across backends with the lookup information that can be provided.
  • Python: add a pyproject.toml to facilitate integration with the Python ecosystem. Thanks @TheStaticTurtle!
  • Windows MIDI Services: support updated to the RC1 release headers.
  • Windows MIDI Services: add support for the newly introduced COM fast-path to provide maximum performance.

Since v5.3

  • Minor bugfixes
  • More MinGW CI
  • Add an example of converting MIDI files to .pat format
  • MSVC ARM64 CI

Since v5.2

  • Minor bugfixes
  • Support detecting presence of ALSA sequencer at runtime
  • Add conversion functions for MIDI 1 <-> 2

Since v5.1

  • Report USB device identifiers with ALSA and udev
  • PipeWire and JACK UMP support (requires PipeWire v1.4+)

Since v5

  • Use stdx::error for error reporting until C++26 and std::error are widely available :-)
  • Hunt exceptions down
  • MIDI 2 support on Windows with the Windows MIDI Services.
  • WinUWP support on MinGW / MSYS2.
  • Getters for USB location, etc. in libremidi::port_information.
  • Reverse-engineered implementation of Mackie Control Universal & Logic Control protocols. Tested with TouchMCU and a BCF2000.
  • C API for bindings to other languages (libremidi-c.h).
  • Python binding.
  • Haskell binding courtesy of @ejconlon λ!
  • Java binding courtesy of @atsushieno!
  • Support for getting raw, unfiltered MIDI data (e.g. no SYSEX recombination logic).
  • Computer Keyboard backend to easily map scancodes to keyboard-like MIDI maps ⌨.
  • Network backend to send MIDI 1 and UMP packets over OSC 🛜.
  • libremidi finally supports MIDI 2 on all desktop platforms 🎉!

Since v4.5

  • Input logic refactored across all backends.
    • e.g. previously not backends had the same rules wrt timestamping, sysexes, etc. Now there is a single MIDI state machine which processes this.
  • PipeWire support.
  • Many bugfixes across the stack.

Since v4.4

  • iOS support restored (thanks @fwcd)
  • CI work: added Debian Bullseye, Bookworm, Trixie and make sure UMP code is being built.
  • Add compatibility with ni-midi2: the libremidi::ump type will convert automatically from / to midi::universal_packet and it is possible to send directly some ni-midi2 data types through libremidi::midi_out.
  • Added an example of very basic MIDI-CI interoperation with MIDI2.0Workbench: https://github.com/jcelerier/libremidi/blob/master/examples/midi2_interop.cpp
  • Observer: add a track_any flag to track MIDI ports that are not reported as being hardware or software.
  • UMP: allow send_ump to handle UMP streams, not only single UMP packets.

Since v4.3

  • Improvements to timing handling.
    • Added a Custom timestamping mechanism which allows the user to provide a custom callback to run timestamping as close as possible to the event's reception.
    • Added midi_in::absolute_timestamp() to get the origin timestamp for driver-provided ticks as accurately as possible.
      • e.g. in practice this is taking the time just near the ALSA queue creation or WinMM MIDI open.
    • Bugfixes in JACK
    • Many warning fixes - thanks @lilggamegenius for the extensive work!
    • Fix MIDI dump example - thanks @chdiesch!
    • Add SOVERSION to dynamic library

Since v4.2

  • More robust MIDI 2.0 support.
    • On macOS through CoreMIDI (input / output, requires macOS 11+).
    • On Linux through ALSA sequencer API (input / output, requires kernel 6.5+ and latest libasound).
    • The API can be used through MIDI 1 or MIDI 2 affordances, e. g. one can send UMP packets to a MIDI 1 API, they will get converted automatically.
    • More backends to come, in particular with the new Windows MIDI Services started here!
    • Sysex handling on MIDI 2.0 is the responsibility of the user of the library, which simplifies the design immensely and allows the library to be used in stricter real-time contexts (as an UMP message has a fixed size, unlike MIDI 1 sysex which required potentially unbounded dynamic allocations with the previous design).
    • See midi_echo.cpp for a complete example.
  • Linux: libasound and udev are now entirely loaded at run-time through dlopen. This is necessary for making apps that will run on older Linux versions which do not have the ALSA UMP APIs yet. Note that to make an app which supports MIDI 2 on recent Linuxes and still runs on older ones, you will need to use the latest ALSA library headers as part of your build on an older distribution, by building alsa-lib yourself (as the old distributions with an old glibc that you want to build against to make compatible software of course also ship an old libasound which won't have the UMP API...).

Since v4

  • Experimental MIDI 2.0 support.
  • A neat configuration system which enables to pass options to the underlying backends.
  • Possibility to share the contexts across inputs and outputs to avoid creating multiple clients in e.g. JACK.
  • Hotplug support for all the backends!
  • Reworked port opening API which now uses handles instead of port indices to increase robustness in the face of disconnection / reconnection of MIDI devices.
  • Integer timestamps everywhere, and in nanoseconds. Additionnally, it is now possible to choose different timestamping methods (e.g. relative, absolute monotonic clock...).
  • Experimental API to allow to poll manually in ALSA (Sequencer and Raw), in order to give more control to the user and enable processing events on any kind of Linux event-loop.
  • Increase the checks done by the MIDI parser.
  • Internally it's pretty much a complete rewrite. Standard threading primitives are now used, as well as modern Linux facilities for polling control (eventfd, timerfd). Most of the code has been refactored.
  • Ability to set a fixed message size for zero-allocation scenarios, with -DLIBREMIDI_SLIM_MESSAGE=<NBytes> (in CMake or directly to the compiler)

Since v3

  • Allow to pass span when available (C++20) or (uint8_t* bytes, std::size_t size) pairs whenever possible to reduce copying.

Since v1

  • The library can be used header-only, as explained in the docs
  • Callbacks are passed by std::function and generally simplified.
  • Ability to use boost::small_vector to pass midi bytes instead of std::vector to reduce allocations.
  • Less indirections, virtuals and memory allocations.
  • Simplify usage of some functions, use C++ return style everywhere.
  • Use of standard C++ snake_case.
  • Simplification of exceptions.
  • Passes clean through clang-tidy, clang analyzer, GCC -Wall -Wextra, ASAN, UBSAN etc etc.
  • Support chunking of output data (only supported on raw ALSA backend so far).

New & improved backends

  • JACK support on Windows.
  • JACK support through weakjack to allow runtime loading of JACK.
  • UWP MIDI support on Windows
  • Emscripten support to run on a web browser with WebMIDI.
  • Raw ALSA support in addition to the existing ALSA sequencer support.

Roadmap

  • Migrate to std::expected instead of exceptions for error handling.
  • Finish MIDI 2 implementations, provide helpers, etc.
  • More tests and compliance checks
  • Work even more towards this library being a zero-cost abstraction on top of native MIDI APIs
  • Rethink some design issues with the original RtMidi, for instance the way port numbers work is not reliable
  • Refactor duplicated code across backends

They use this library

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pylibremidi-5.3.1.tar.gz (15.7 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

pylibremidi-5.3.1-cp314-cp314t-win_amd64.whl (652.5 kB view details)

Uploaded CPython 3.14tWindows x86-64

pylibremidi-5.3.1-cp314-cp314t-win32.whl (597.5 kB view details)

Uploaded CPython 3.14tWindows x86

pylibremidi-5.3.1-cp314-cp314t-musllinux_1_2_x86_64.whl (918.8 kB view details)

Uploaded CPython 3.14tmusllinux: musl 1.2+ x86-64

pylibremidi-5.3.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (463.1 kB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

pylibremidi-5.3.1-cp314-cp314t-macosx_11_0_arm64.whl (430.7 kB view details)

Uploaded CPython 3.14tmacOS 11.0+ ARM64

pylibremidi-5.3.1-cp310-abi3-win_amd64.whl (632.4 kB view details)

Uploaded CPython 3.10+Windows x86-64

pylibremidi-5.3.1-cp310-abi3-win32.whl (582.9 kB view details)

Uploaded CPython 3.10+Windows x86

pylibremidi-5.3.1-cp310-abi3-musllinux_1_2_x86_64.whl (912.0 kB view details)

Uploaded CPython 3.10+musllinux: musl 1.2+ x86-64

pylibremidi-5.3.1-cp310-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (457.9 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

pylibremidi-5.3.1-cp310-abi3-macosx_11_0_arm64.whl (427.1 kB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

File details

Details for the file pylibremidi-5.3.1.tar.gz.

File metadata

  • Download URL: pylibremidi-5.3.1.tar.gz
  • Upload date:
  • Size: 15.7 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pylibremidi-5.3.1.tar.gz
Algorithm Hash digest
SHA256 2da000d0218846e7b412c2960c842ac7d3d62bd76270cc04668d4c0e8e6a3cb0
MD5 a2bd0d6e3699ade72cf4b9e82b65f584
BLAKE2b-256 74b22f709021e2e7c6eb1e541627b4706f65b33421ad8c52eefb9b55bd679ed2

See more details on using hashes here.

Provenance

The following attestation bundles were made for pylibremidi-5.3.1.tar.gz:

Publisher: publish_pypi.yml on celtera/libremidi

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pylibremidi-5.3.1-cp314-cp314t-win_amd64.whl.

File metadata

File hashes

Hashes for pylibremidi-5.3.1-cp314-cp314t-win_amd64.whl
Algorithm Hash digest
SHA256 61b6c3d1ed69d374aa916e0fef00f99b7c43dee6e3ad7786a592e9d8cfbd869b
MD5 f89da3e3360ffed167ecccf8c99e4b49
BLAKE2b-256 6932d4c71276b401bb5cc17e753930bcf095df04eaaec721908ee7a33212527f

See more details on using hashes here.

Provenance

The following attestation bundles were made for pylibremidi-5.3.1-cp314-cp314t-win_amd64.whl:

Publisher: publish_pypi.yml on celtera/libremidi

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pylibremidi-5.3.1-cp314-cp314t-win32.whl.

File metadata

  • Download URL: pylibremidi-5.3.1-cp314-cp314t-win32.whl
  • Upload date:
  • Size: 597.5 kB
  • Tags: CPython 3.14t, Windows x86
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pylibremidi-5.3.1-cp314-cp314t-win32.whl
Algorithm Hash digest
SHA256 c90461ad02f08d24cd4ee8d0ce17214e4917716a07bd71dbf15897407251cfdc
MD5 5cd6d06766ac245304b0c0e6f0ec9c4a
BLAKE2b-256 0f528157e9004b7acab6e7bfdbbddb69f9d105037bc44be582773ea94f6a0a1c

See more details on using hashes here.

Provenance

The following attestation bundles were made for pylibremidi-5.3.1-cp314-cp314t-win32.whl:

Publisher: publish_pypi.yml on celtera/libremidi

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pylibremidi-5.3.1-cp314-cp314t-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for pylibremidi-5.3.1-cp314-cp314t-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 0031928fae04dc18fb09ee1cada4fb0822ca3d3a1d0d117e283848af209dee03
MD5 d106827b30e25f4672515c4d59efadf5
BLAKE2b-256 6a5c4e7d04ef3ac495b73e9ded5cb4422633025fd8f070dbc6964fdeb805818d

See more details on using hashes here.

Provenance

The following attestation bundles were made for pylibremidi-5.3.1-cp314-cp314t-musllinux_1_2_x86_64.whl:

Publisher: publish_pypi.yml on celtera/libremidi

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pylibremidi-5.3.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pylibremidi-5.3.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 e11c4a7b7f6a91ba888ce0d47a8ce556825a72664ff53c8b5eddf33af1bdecea
MD5 d92ec5d1cda2c419664ee3b60c183533
BLAKE2b-256 1ede98726f988ecc9b61c02d0fbeceb546bf9bb120eda0a6a24a3903b6c330a5

See more details on using hashes here.

Provenance

The following attestation bundles were made for pylibremidi-5.3.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: publish_pypi.yml on celtera/libremidi

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pylibremidi-5.3.1-cp314-cp314t-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pylibremidi-5.3.1-cp314-cp314t-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f0f7bf25bf0e0bca42d9660d21e2721b93bbef6232d0debfd5e4596737c20782
MD5 896ba7aa8feba13367763963f542fec3
BLAKE2b-256 e1ec9d5206ab599ee8e039ce3907a57dab51d1add23aab3d323dea42fe70f419

See more details on using hashes here.

Provenance

The following attestation bundles were made for pylibremidi-5.3.1-cp314-cp314t-macosx_11_0_arm64.whl:

Publisher: publish_pypi.yml on celtera/libremidi

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pylibremidi-5.3.1-cp310-abi3-win_amd64.whl.

File metadata

  • Download URL: pylibremidi-5.3.1-cp310-abi3-win_amd64.whl
  • Upload date:
  • Size: 632.4 kB
  • Tags: CPython 3.10+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pylibremidi-5.3.1-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 cafb6423a7e02ebc9bc638df9ab68e8577041cb7154f8dc86d3619357cb81781
MD5 6da35fdd7a29171a1e72585e21e70fea
BLAKE2b-256 c2ab26c29b53c063df963a1bc8ba14773ef23d621a044b018ef805401ffecc4b

See more details on using hashes here.

Provenance

The following attestation bundles were made for pylibremidi-5.3.1-cp310-abi3-win_amd64.whl:

Publisher: publish_pypi.yml on celtera/libremidi

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pylibremidi-5.3.1-cp310-abi3-win32.whl.

File metadata

  • Download URL: pylibremidi-5.3.1-cp310-abi3-win32.whl
  • Upload date:
  • Size: 582.9 kB
  • Tags: CPython 3.10+, Windows x86
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pylibremidi-5.3.1-cp310-abi3-win32.whl
Algorithm Hash digest
SHA256 9f21cb0ed786d25503859ac5c28e1208c0b62bd28d595e406034b9b20cf8ebcf
MD5 474053362bbc1c956e84f0ffb4992f5b
BLAKE2b-256 8c96344acff3f09c448a00da7d7975d5e312c60e10cf7907a8204dfd4ffd2a5c

See more details on using hashes here.

Provenance

The following attestation bundles were made for pylibremidi-5.3.1-cp310-abi3-win32.whl:

Publisher: publish_pypi.yml on celtera/libremidi

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pylibremidi-5.3.1-cp310-abi3-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for pylibremidi-5.3.1-cp310-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 b047321906d819404931098c5104fe861cfe1f95b628f1154566d897f2645041
MD5 f468052d8308db555a29cc3de780c223
BLAKE2b-256 02ec71a9df29ee351e1ec5f1ee22e0c8fe1931b73114e47551b3daddc5e4e73d

See more details on using hashes here.

Provenance

The following attestation bundles were made for pylibremidi-5.3.1-cp310-abi3-musllinux_1_2_x86_64.whl:

Publisher: publish_pypi.yml on celtera/libremidi

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pylibremidi-5.3.1-cp310-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pylibremidi-5.3.1-cp310-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 1e15a4a3dc8d02f2a233769cd8f8b43fab67f50683606e6234b48088a1398d67
MD5 e25a8d8d419d67af6985f4cae082dbc0
BLAKE2b-256 94068d9e0fc34056486b6ca0c32dabddd893b1205fcc5daeb5de1f1e4cecd251

See more details on using hashes here.

Provenance

The following attestation bundles were made for pylibremidi-5.3.1-cp310-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: publish_pypi.yml on celtera/libremidi

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pylibremidi-5.3.1-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pylibremidi-5.3.1-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 fb26bcb5203ea31be0529a160b8e7d890cbad1448314a54aa34e1398febed939
MD5 7fd9e4a2a21d1f627af3b520016f78bc
BLAKE2b-256 a382f5a989902b1caed14cc42f2c2b90e9df7235734e2f237601691030d37cbd

See more details on using hashes here.

Provenance

The following attestation bundles were made for pylibremidi-5.3.1-cp310-abi3-macosx_11_0_arm64.whl:

Publisher: publish_pypi.yml on celtera/libremidi

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page