没有声音。 通过RubyDL使用Ruby和winmm

预期的行为:中间C在一个midi instrunment,然后另一个。 实际行为:DL弃用警告并且没有声音。 运行Windows 7。

代码:

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 module C extend DL::Importer 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::Importer.sizeof("int")) 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(DL::CPtr.to_ptr(@device).to_i, message) end end midi = LiveMIDI.new midi.note_on(0, 60, 100) sleep(1) midi.note_off(0, 60) midi.program_change(1, 40) midi.note_on(1, 60, 100) sleep(1) midi.note_off(1, 60) 

从实用ruby项目采取。 通过页面上的数字,11-15,在第2章中。代码稍作修改,以处理Ruby 1.9中对Ruby DL的更改。

你必须写

 DL::CPtr.malloc(DL::Importer.sizeof("int") 

代替

 DL.malloc(DL::Importer.sizeof("int")) 

创建一个指针对象( DL::CPtr ),而不仅仅是一个整数的地址。

 DL::CPtr.to_ptr(@device).to_i 

必须

 @device.ptr.to_i 

甚至可能是

 @device.ptr 

下面是使用DL更换小提琴的固定版本的代码:

 require 'fiddle/import' require 'fiddle/types' 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 module C extend Fiddle::Importer dlload 'winmm' # defines a few Windows-specific types such as DWORD or UINT include Fiddle::Win32Types # some other types not defined by the previous line typealias 'HMIDIOUT', 'void*' typealias 'LPHMIDIOUT', 'HMIDIOUT*' typealias 'DWORD_PTR', 'uintptr_t' typealias 'MMRESULT', 'UINT' extern 'MMRESULT midiOutOpen(LPHMIDIOUT, UINT, DWORD_PTR, DWORD_PTR, DWORD)' extern 'MMRESULT midiOutClose(HMIDIOUT)' extern 'MMRESULT midiOutShortMsg(HMIDIOUT, DWORD)' end def open @device = Fiddle::Pointer.malloc(Fiddle::SIZEOF_VOIDP) C.midiOutOpen(@device, -1, 0, 0, 0) end def close C.midiOutClose(@device.ptr) end def message(one, two = 0, three = 0) message = one + (two << 8) + (three << 16) C.midiOutShortMsg(@device.ptr, message) end end 

除了根据MSDN上的文档添加或更正的类型内容外,其他内容都差不多。 错误的类型可能会导致不明显的问题。