首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >没有声音。通过RubyDL使用Ruby和winmm

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

Stack Overflow用户
提问于 2015-09-17 04:08:36
回答 1查看 48关注 0票数 2

预期行为:中间C在一个midi指令上玩,然后在另一个工具上玩。实际行为: DL降级警告,没有声音。运行Windows 7。

守则:

代码语言:javascript
复制
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页上的数字,对代码做了一些修改,以处理Ruby1.9中对Ruby的更改。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-09-17 07:27:42

你得写

代码语言:javascript
复制
DL::CPtr.malloc(DL::Importer.sizeof("int")

而不是

代码语言:javascript
复制
DL.malloc(DL::Importer.sizeof("int"))

要创建指针对象(DL::CPtr),而不只是获得整数的地址。

也是

代码语言:javascript
复制
DL::CPtr.to_ptr(@device).to_i

一定是

代码语言:javascript
复制
@device.ptr.to_i

或者甚至

代码语言:javascript
复制
@device.ptr

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

代码语言:javascript
复制
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的文档。错误的类型可能导致不明显的问题。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32622432

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档