Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save aberant/436952 to your computer and use it in GitHub Desktop.

Select an option

Save aberant/436952 to your computer and use it in GitHub Desktop.
require 'ffi'
class MIDISysexSendRequest < FFI::Struct
layout :destination, :pointer,
:data, :pointer,
:bytes_to_send, :uint32,
:complete, :int,
:reserved, [:char, 3],
:completion_proc, :pointer,
:completion_ref_con, :pointer
end
module C
extend FFI::Library
ffi_lib '/System/Library/Frameworks/CoreMIDI.framework/Versions/Current/CoreMIDI'
attach_function :MIDIGetDevice, [:int], :pointer
attach_function :MIDIDeviceGetEntity, [:pointer, :int], :pointer
attach_function :MIDIEntityGetDestination, [:pointer, :int], :pointer
attach_function :MIDISendSysex, [:pointer], :int
end
# hardcode it to my IAC driver and bus 1 entity
device = C.MIDIGetDevice( 0 )
entity = C.MIDIDeviceGetEntity( device, 0 )
end_point = C.MIDIEntityGetDestination( entity, 0 )
CALLBACK = FFI::Function.new( :void, [:pointer] ) do | sysex_request_ptr |
# it never prints out anything.. hmm...
puts sysex_request_ptr[:complete]
end
# lets pretend we are sending a GS reset to a roland
hex = %w(F0 41 10 42 12 40 00 7F 00 41 F7)
sysex_data = hex.map{ |h| h.hex }
format = "C" * sysex_data.size
bytes = FFI::MemoryPointer.new FFI.type_size(:char) * sysex_data.size
bytes.write_string sysex_data.pack(format)
request = MIDISysexSendRequest.new
request[:destination] = end_point
request[:data] = bytes
request[:bytes_to_send] = sysex_data.size
request[:complete] = 0
request[:completion_proc] = CALLBACK
request[:completion_ref_con] = request
C.MIDISendSysex(request)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment