Library / SDK
thestk/rtmidi avatar
thestk/rtmidi

RtMidi: one C++ MIDI API across six platforms

A set of C++ classes that provide a common API for realtime MIDI input/output across Linux (ALSA & JACK), Macintosh OS X (CoreMIDI) and Windows (Multimedia)

1,216 stars314 forksC++NOASSERTION

At a glance

What is it?
RtMidi is a set of C++ classes that hide the platform MIDI backends, ALSA and JACK on Linux, CoreMIDI on macOS, the Multimedia library and UWP on Windows, plus Web MIDI, iOS and Android. It is a thin layer by design, with one header and one source file, and it deliberately does not do timing, which is the choice that shapes how you use it.
Who is it for?
RtMidi fits a C++ project that has to talk to MIDI hardware on more than one operating system, or that wants the same device enumeration code on Linux, macOS and Windows without three vendor SDKs. It does not fit a project that needs sample accurate scheduling, since output messages are sent immediately and the library provides no timing functionality at all, and it does not fit a project that cannot accept a licence that asks for modifications to be sent to the developer.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 7 days ago.
What is it written in?
Mainly C++, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

One API, many backends

RtMidi is a set of C++ classes that provide a common API for realtime MIDI input and output across Linux with ALSA and JACK, Macintosh OS X with CoreMIDI and JACK, and Windows with the Multimedia Library and UWP, and the README also lists Web MIDI, iOS and Android.

The classes are RtMidiIn, RtMidiOut, and API specific classes for the individual backends. The design goals are listed and they are worth reading as a set, because they explain the shape of the library.

Object oriented C++ design. A simple, common API across all supported platforms. Only one header and one source file for easy inclusion in programming projects. And MIDI device enumeration.

That third goal is the one that decides how you will use it. A single header and a single source file means you can drop RtMidi into a project by copying two files, or by compiling the source into your build, without a package manager, a shared library or a dependency tree. For a library that has been in use since 2003 and predates most of the current packaging conventions, that was the right decision and it is still the reason it survives in codebases nobody touches.

The author is Gary P. Scavone, and the copyright line in the README covers 2003 to 2023. The library is also on Conan Center, so a modern build system can fetch it without the copy and paste step.

The distribution contains two directories, doc for the documentation, which is also online, and tests for the example programs.

Two classes, one connection each, and no timing

The overview section is where the design limits are stated, and they are stated early.

MIDI input and output functionality are separated into two classes, RtMidiIn and RtMidiOut, and each class instance supports only a single MIDI connection. So a program that talks to three devices has three objects, and there is no multi-port abstraction hiding that.

Then the sentence that decides the use case: RtMidi does not provide timing functionality, meaning output messages are sent immediately. Input messages are timestamped with delta times in seconds, through a double floating point type, and MIDI data is passed to the user as raw bytes using a std::vector<unsigned char>.

The absence of timing is a deliberate scope decision rather than an omission, and it is the right one for a library whose job is to abstract the platform API. Sample accurate scheduling is a different discipline, with different requirements, and a library that tried to do both would be worse at each. But it means the calling code owns the clock, and a DAW written on top of RtMidi is using a separate timing layer entirely.

The raw bytes and the double timestamps are the other half of the contract. RtMidi does not parse the MIDI message for you, it hands over the status byte and the data bytes, and the timestamps are deltas rather than absolute times, so the consumer also owns the conversion from a delta stream to a timeline.

Building: autotools, CMake, and the backend switches

The build instructions are short and cover both build systems.

On Unix systems you run ./configure and then make in the top level directory, which builds both the library and the test programs in tests/. For installation and building on Windows there is a WINDOWS.md, and if you checked the code out from git you need to run ./autogen.sh before ./configure.

The configure script has a help that lists the available MIDI API options, with --with-alsa, --with-jack, --with-core and --with-winmm, and by default the ones appropriate to the system are selected. RtMidi can also be built with CMake, which is the path the Android support requires.

The Linux detail is the one that catches people. ALSA support needs its development files, libasound2-dev on Debian and Ubuntu and alsa-lib-devel on Fedora, and without them both ./configure and the CMake build succeed without ALSA. The configure script may then find no MIDI API at all if no other backend is available, which is a confusing outcome for a build that reported success.

The Android support uses the AMidi API and must be built with CMake, with its own README.

The repository carries the full autotools machinery, configure.ac, Makefile.am, the m4 macros, autogen.sh, and a CMakeLists.txt with a cmake/ directory, plus the pkg-config template files, rtmidi-config.in and rtmidi.pc.in, so a system install exposes itself properly to other build systems.

The macro rename that C++ forced

If you compile RtMidi.cpp yourself, you define the backends you want, and the names to use are the API macros.

cpp
RTMIDI_API_ALSA
RTMIDI_API_JACK
RTMIDI_API_CORE
RTMIDI_API_WINMM
RTMIDI_API_WMS
RTMIDI_API_UWP
RTMIDI_API_WEBMIDI
RTMIDI_API_AMIDI

And there is a story behind the change, which the README tells with a reference to issue 133. These names replace the previous ones, __LINUX_ALSA__, __UNIX_JACK__, __MACOSX_CORE__, __WINDOWS_MM__ and the other names that begin with two underline characters, because C++ reserves identifiers that start with an underscore followed by a capital letter. Using them was technically a violation of the standard, and the project fixed it by renaming the macros rather than by asking users to change their build flags at once.

The old names still work in 6.x, but they are deprecated and will be removed in 7.0.0. That is a well handled deprecation, and it is also the one thing in this repository that will break a build eventually, so it belongs on the upgrade checklist along with the ALSA development packages and the Windows COM detail.

For debugging there is a separate RTMIDI_DEBUG define for debug output, which is worth knowing about before you start guessing why a backend is not enumerating devices.

A module, a C API, and the COM call on Windows

Three smaller features complete the picture.

RtMidi is also offered as a module, enabled with RTMIDI_BUILD_MODULES and accessed with import rt.midi. Namespaces are implicitly imported unless you disable that with RTMIDI_USE_NAMESPACE, so a class can be reached through the rt::midi namespace or through the global namespace, and the README gives both forms, rt::midi::MidiApi and ::MidiApi, as valid. The module build is what lets the same library serve a C++ project and a language with a module system without two copies of the code.

There is a C API as well, in the form of rtmidi_c.cpp and rtmidi_c.h, for projects that are not C++.

And on Windows there is a wrinkle that the README documents under its own heading. In some cases, for example to use RtMidi with GS Synth, it may be necessary for your program to call CoInitializeEx and CoUninitialize on entry to and exit from the thread that uses RtMidi. That is a COM initialisation requirement leaking out of the platform API, and it is the kind of detail that turns into an intermittent crash on a thread you did not initialise.

The complete documentation is in the doc directory of the distribution, and it is also online at the address the README links.

A licence like MIT, with one extra condition

The legal section is two sentences and it is not quite a standard licence.

The RtMidi licence is similar to the MIT License, with the added feature that modifications be sent to the developer.

That is the old style of clause, familiar from the 1990s and early 2000s, where a permissive licence carries an obligation to send patches back. It is unusual now, and it has an obvious tension with the way the licence is otherwise structured: an MIT style licence grants rights without conditions, and this one adds a condition on modification.

The practical reading is that using RtMidi unmodified, or in a way nobody asks about, has no obligations at all. If you want to modify the library itself, the licence asks you to send the change to the developer, which in practice means the project would like to see it. Whether that is a condition you can comply with depends on your relationship with the upstream author, and on your own legal advice, which is not something this article can settle.

The file to read is LICENSE, and the README points at it. Everything else about the project, from the single header design to the twenty year history, points to it being used exactly as it ships.

Editorial conclusion

RtMidi fits a C++ project that has to talk to MIDI hardware on more than one operating system, or that wants the same device enumeration code on Linux, macOS and Windows without three vendor SDKs. It does not fit a project that needs sample accurate scheduling, since output messages are sent immediately and the library provides no timing functionality at all, and it does not fit a project that cannot accept a licence that asks for modifications to be sent to the developer. Verify three things before you build on it: which backends you need and whether your system has the development files for them, because a missing ALSA development package produces a build with no MIDI support rather than an error, whether the API macro names you are used to still work, since the old underscore names are deprecated and will be removed in 7.0.0, and whether your own thread needs COM initialised on Windows, which is not automatic.

Frequently asked questions

What platforms does RtMidi support?

The common API covers realtime MIDI input and output across Linux with ALSA and JACK, Macintosh OS X with CoreMIDI and JACK, and Windows with the Multimedia Library and UWP, and the README also lists Web MIDI, iOS and Android. Android uses the AMidi API and must be built with CMake.

Does RtMidi handle MIDI timing?

No. The README states that RtMidi does not provide timing functionality, so output messages are sent immediately. Input messages are timestamped with delta times in seconds through a double, and MIDI data is passed as raw bytes in a std::vector<unsigned char>, so the calling code owns the clock and the parsing.

How do I build RtMidi?

On Unix systems run ./configure and then make, and if you checked the code out from git run ./autogen.sh first. The configure script has a help listing the MIDI API options --with-alsa, --with-jack, --with-core and --with-winmm, and it can also be built with CMake. For Windows, WINDOWS.md covers installation and building.

What are the RTMIDI_API macros and what happened to the old names?

They are the backend selection defines, RTMIDI_API_ALSA, RTMIDI_API_JACK, RTMIDI_API_CORE, RTMIDI_API_WINMM, RTMIDI_API_WMS, RTMIDI_API_UWP, RTMIDI_API_WEBMIDI and RTMIDI_API_AMIDI. They replaced the earlier names such as __LINUX_ALSA__ and __WINDOWS_MM__ because C++ reserves identifiers that begin with two underline characters followed by a capital letter. The old names still work in 6.x but are deprecated and will be removed in 7.0.0.

What licence is RtMidi under?

The README describes the licence as similar to the MIT License, with the added feature that modifications be sent to the developer. The full terms are in the LICENSE file, and the author is Gary P. Scavone, with the copyright line covering 2003 to 2023.

Official sources

  1. Issues
  2. README
  3. Releases
  4. thestk/rtmidi on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/thestk-rtmidi.svg)](https://hysenlabs.com/projects/thestk-rtmidi)

Was this useful?