MIDI Events

Ruby Version License

Ruby MIDI Events Objects

This library is part of a suite of Ruby libraries for MIDI:

Function Library
MIDI Events representation MIDI Events
MIDI Data parsing MIDI Parser
MIDI communication with Instruments and Control Surfaces MIDI Communications
Low level MIDI interface to MacOS MIDI Communications MacOS Layer
Low level MIDI interface to Windows MIDI Communications Windows Layer
Low level MIDI interface to Linux TO DO (by now MIDI Communications uses alsa-rawmidi)
Low level MIDI interface to JRuby TO DO (by now MIDI Communications uses midi-jruby)

This library is based on Ari Russo's library MIDI Message.

Features

Install

gem install midi-events

Or if you're using Bundler, add this to your Gemfile

gem "midi-events"

Usage

require "midi-events"

Basic Messages

There are a few ways to create a new MIDI event. Here are some examples:

MIDIEvents::NoteOn.new(0, 64, 64)

MIDIEvents::NoteOn["E4"].new(0, 100)

MIDIEvents.with(:channel => 0, :velocity => 100) { note_on("E4") }

Those expressions all evaluate to the same object:

#<MIDIEvents::NoteOn:0x9c1c240
   @channel=0,
   @data=[64, 64],
   @name="E4",
   @note=64,
   @status=[9, 0],
   @velocity=64,
   @verbose_name="Note On: E4">

Raw Channel Messages

You can also create raw channel messages directly from nibbles and bytes:

MIDIEvents::ChannelMessage.new(0x9, 0x0, 0x40, 0x40)

Mutable Properties

Some message properties can be modified after creation:

msg = MIDIEvents::NoteOn["E4"].new(0, 100)
msg.note += 5  # Transpose up 5 semitones

System Realtime Messages

System Realtime messages are used for synchronization:

MIDIEvents::SystemRealtime["Start"].new
MIDIEvents::SystemRealtime["Stop"].new

Building Melodies

You can construct sequences of notes programmatically:

channel = 0
notes = [36, 40, 43]  # C E G
octaves = 2
velocity = 100

melody = []

(0..((octaves-1)*12)).step(12) do |oct|
  notes.each { |note| melody << MIDIEvents::NoteOn.new(channel, note + oct, velocity) }
end

SysEx Messages

As with any kind of message, you can begin with raw data:

MIDIEvents::SystemExclusive.new(0xF0, 0x41, 0x10, 0x42, 0x12, 0x40, 0x00, 0x7F, 0x00, 0x41, 0xF7)

Or in a more object oriented way:

synth = SystemExclusive::Node.new(0x41, model_id: 0x42, device_id: 0x10)

SystemExclusive::Command.new([0x40, 0x7F, 0x00], 0x00, node: synth)

A Node represents a device that you're sending a message to (eg. your Yamaha DX7 is a Node). Sysex messages can either be a Command or Request.

You can use the Node to instantiate a message:

synth.command([0x40, 0x7F, 0x00], 0x00)

One way or another, you will wind up with a pair of objects like this:

#<MIDIEvents::SystemExclusive::Command:0x9c1e57c
   @address=[64, 0, 127],
   @checksum=[65],
   @data=[0],
   @node=
    #<MIDIMessage::SystemExclusive::Node:0x9c1e5a4
     @device_id=16,
     @manufacturer_id=65,
     @model_id=66>>

Documentation

Differences between MIDI Events library and MIDI Message library

MIDI Events is mostly a clone of MIDI Message with some modifications:

  • Renamed gem to midi-events instead of midi-message
  • Renamed module to MIDIEvents instead of MIDIMessage
  • Removed parsing features (in favour of the more complete parser MIDI Parser)

Then, why does exist this library if it is mostly a clone of another library?

The author has been developing since 2016 a Ruby project called Musa DSL that needs a way of representing MIDI Events and a way of communicating with MIDI Instruments and MIDI Control Surfaces.

Ari Russo has done a great job creating several interdependent Ruby libraries that allow MIDI Events representation (MIDI Message and Nibbler) and communication with MIDI Instruments and MIDI Control Surfaces (unimidi, ffi-coremidi and others) that, with some modifications, I've been using in MusaDSL.

After thinking about the best approach to publish MusaDSL I've decided to publish my own renamed version of the modified dependencies because:

  • The original libraries have features (buffering, very detailed logging and processing history information, not locking behaviour when waiting input midi messages) that are not needed in MusaDSL and, in fact, can degrade the performance on some use cases in MusaDSL.
  • The requirements for Musa DSL users probably will evolve in time, so it will be easier to maintain an independent source code base.
  • Some differences on the approach of the modifications vs the original library doesn't allow to merge the modifications on the original libraries.
  • Then the renaming of the libraries is needed to avoid confusing existent users of the original libraries.
  • Due to some of the interdependencies of Ari Russo libraries, the modification and renaming on some of the low level libraries (ffi-coremidi, etc.) forces to modify and rename unimidi library.

All in all I have decided to publish a suite of libraries optimized for MusaDSL use case that also can be used by other people in their projects.

Author

Acknowledgements

Thanks to Ari Russo for his ruby library MIDI Message licensed as Apache License 2.0.

License

MIDI Events is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. See LICENSE.

What this means for you. Composing, performing and publishing music made with MIDI Events carries no obligation: the music is yours. The GPL applies to software: if you distribute a program that includes or is built on MIDI Events, that program must be released under the GPL too, with its source.

Commercial license. If you need MIDI Events under terms its license does not cover — for instance, inside a closed product — yeste.studio offers a commercial license. Write to [email protected].

Versions. From 1.0.0, MIDI Events follows Semantic Versioning: breaking changes only come with a new major version.

MIDI Events Copyright (c) 2021-2026 yeste.studio

This library is based on Ari Russo's MIDI Message, Copyright (c) 2011-2015 Ari Russo, distributed under the Apache License 2.0; see LICENSE.midi-message. Files modified by yeste.studio.