Introduction to MIDI: Part 1


Or rather, how to use MIDI on the BeOS and, of course, Haiku. MIDI stands for Musical Instrument Digital Interface and is a well-established protocol for controlling musical devices such as keyboards, synthesizers, drum computers, and a whole bunch of other stuff. The protocol is fairly simple and consists of commands such as "play this note" and "now use this instrument". You don't need to be a MIDI expert to write BeOS MIDI apps, but some knowledge of the protocol helps. I won't go into the MIDI protocol in this article, so you may want to check out the MIDI Technical Fanatic's Brainwashing Center, and of course

At this time of writing, the Haiku Midi Kit is not finished yet, but you can already start experimenting under BeOS R5. After all, both kits will be binary compatible, so when Haiku is finished, it can run your MIDI apps without any problems.

The two kits

The BeOS actually comes with two different, but compatible Midi Kits. This article focuses on the "new" Midi Kit that was introduced with BeOS R5. The old kit, which we'll refer to as midi1, is more complete than the new kit, but less powerful. Both kits let you create so-called MIDI endpoints, but the endpoints from the midi1 kit cannot be shared between different applications. The midi2 kit solves that problem, but unlike midi1 it does not include a General MIDI softsynth, nor does it have a facility for reading and playing Standard MIDI Files. Don't worry: both kits are compatible and you can mix-and-match them in your applications.

The old kit is pretty well documented in the BeBook, but the new kit unfortunately isn't. For the time being, you can find preliminary midi2 documentation at the Haiku Midi Team website. I suggest that you read through it, especially the introduction. In the future, we will clean up the docs and move them into the Haiku source code tree where they belong.

Endpoints and the roster

The purpose of the midi2 kit is to manage MIDI endpoints. An endpoint is like a MIDI In or MIDI Out socket on your equipment; it either receives information or it sends information. Endpoints that send MIDI events are called producers; the endpoints that receive those events are called consumers.

If your sound card has a MIDI port, for example, then the midi_server (which does all the behind-the-scenes work for the midi2 kit) publishes a consumer and producer endpoint for that port. But an endpoint doesn't necessarily have to correspond to a hardware device; you can also make filters that process and modify MIDI events before passing them on. The source code that accompanies this article demonstrates how to build such a filter.

Central to the midi2 kit is the Midi Roster, which allows you to find available endpoints, and publish your own endpoints. It also lets you make and break connections. Your applications will use the roster to create networks of MIDI objects, and stream MIDI events between them.

If you want to see which MIDI endpoints are currently available in your system, download PatchBay or PatchStudio. These applications show all the available endpoints, and provide a convenient interface for connecting and disconnecting them.


To demonstrate how to program the midi2 kit, I have constructed EchoDemo, a simple application that adds echoes to all incoming notes. You can download it from here. In other words, it plays the same note several times in a row, each a little softer. The app doesn't look like much, but it does touch on most of midi2 kit's capabilities.

EchoDemo publishes a consumer endpoint and a producer endpoint. This combination of a consumer and a producer is commonly called a filter. The consumer receives incoming events, the filter processes them, and finally the producer sends out the filtered events. In our case, the filter sends out extra notes for every "note on" event.

EchoDemo's window contains two list controls: the one on the left shows all the producer endpoints that you can hook up to the filter's input, and the one on the right lists the consumers that you can connect to the filter's output. Simply click in a list to connect a producer or consumer; hold down Shift to connect multiple endpoints. The window also contains two sliders that let you set the number of echo notes and how much delay there is between these notes.

A filter by itself is pretty useless, so you need two extra applications to play with EchoDemo. I suggest you hook up Midi Keyboard to the filter's input and InternalMIDI to its output. That way you can play notes on the virtual keyboard, the filter will add echo notes, and InternalMIDI will play back everything using the General MIDI softsynth.

For even more fun, load up PatchBay and notice that its window now also shows the filter's input and output endpoints. Also notice that if you use PatchBay to connect endpoints to the filter, EchoDemo's list views automatically update their selections. The roster notifies midi2 applications about such changes, so they can update their screens in real time.

Time's up

That's it for now. Rather than repeating most of the source code here to explain how EchoDemo works, I made the source speak for itself. I have tried to keep things as simple as possible, and added comments to most of the tricky stuff. Don't forget to read the midi2 kit documentation as well.

So if this was part 1, there will be a part 2, right? Yes, because the echo filter still has a few problems, which mostly have to do with timing. Crank up the delay to 1000 milliseconds and try rapidly hitting a bunch of notes. You'll find that the playback really lags. In the second part of this article I will explain why this is and provide a solution. See you then!