Skip to content

Instantly share code, notes, and snippets.

@bryanwoods
Created February 13, 2009 22:34
Show Gist options
  • Save bryanwoods/64141 to your computer and use it in GitHub Desktop.
Save bryanwoods/64141 to your computer and use it in GitHub Desktop.
require 'dl/import'
class LiveMIDI
ON = 0x90
OFF = 0X80
PC = 0XC0
def initialize
open
end
def note_on(channel, note, velocity=64)
message(ON | channel, note, velocity)
end
def note_off(channel, note, velocity=64)
message(OFF | channel, note, velocity)
end
def program_change(channel, preset)
message(PC | channel, preset)
end
end
if RUBY_PLATFORM.include?('mswin')
class LiveMIDI
module C
extend DL::Importable
dlload 'winmm'
extern "int midiOutOpen(HMIDIOUT*, int, int, int, int)"
extern "int midiOutClose(int)"
extern "int midiOutShortMsg(int, int)"
end
def open
@device = DL.malloc(DL.sizeof('I'))
C.midiOutOpen(@device, -1, 0, 0, 0)
end
def close
C.midiOutClose(@device.ptr.to_i)
end
def message(one, two=0, three=0)
message = one + (two << 8) + (three << 16)
C.midiOutShortMsg(@device.ptr.to_i, message)
end
end
elsif RUBY_PLATFORM.include?('darwin')
class NoMIDIDestinations < Exception ; end
class LiveMIDI
module C
extend DL::Importable
dlload '/System/Library/Frameworks/CoreMIDI.framework/Versions/Current/CoreMIDI'
extern "int MIDIClientCreate(void *, void *, void *, void *)"
extern "int MIDIClientDispose(void *)"
extern "int MIDIGetNumberOfDestinations()"
extern "void * MIDIGetDestination(int)"
extern "int MIDIOutputPortCreate(void *, void *, void *)"
extern "void * MIDIPacketListInit(void *)"
extern "void * MIDIPacketListAdd(void *, int, void *, int, int, int, void *)"
extern "int MIDISend(void *, void *, void *)"
end
module CF
extend DL::Importable
dlload '/System/Library/Frameworks/CoreFoundation.framework/Versions/Current/CoreFoundation'
extern "void * CFStringCreateWithCString (void *, char *, int)"
end
def open
client_name = CF.cFStringCreateWithCString(nil, "RubyMIDI", 0)
@client = DL::PtrData.new(nil)
C.mIDIClientCreate(client_name, nil, nil, @client.ref);
port_name = CF.cFStringCreateWithCString(nil, "Output", 0)
@outport = DL::PtrData.new(nil)
C.mIDIOutputPortCreate(@client, port_name, @outport.ref);
num = C.mIDIGetNumberOfDestinations()
raise NoMIDIDestinations if num < 1
@destination = C.mIDIGetDestination(0)
end
def close
C.mIDIClientDispose(@client)
end
def message(*args)
format = "C" * args.size
bytes = args.pack(format).to_ptr
packet_list = DL.malloc(256)
packet_ptr = C.mIDIPacketListInit(packet_list)
# Pass in two 32 bit 0s for the 64 bit time
packet_ptr = C.mIDIPacketListAdd(packet_list, 256, packet_ptr, 0, 0, args.size, bytes)
C.mIDISend(@outport, @destination, packet_list)
end
end
elsif RUBY_PLATFORM.include?('linux')
class LiveMIDI
# Linux code here
end
else
raise "Couldn't find a LiveMIDI implementation for your platform"
end
midi = LiveMIDI.new
4.times do
midi.note_on(0, 40, 100)
sleep(0.8)
midi.note_off(0, 40)
midi.note_on(0, 41, 100)
sleep(0.8)
midi.note_off(0, 41)
end
8.times do
midi.note_on(0, 40, 100)
sleep(0.4)
midi.note_off(0, 40)
midi.note_on(0, 41, 100)
sleep(0.4)
midi.note_off(0, 41)
end
12.times do
midi.note_on(0, 40, 100)
sleep(0.2)
midi.note_off(0, 40)
midi.note_on(0, 41, 100)
sleep(0.2)
midi.note_off(0, 41)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment