从 GO 读取 MIDI 输入

Reading MIDI input from GO

我想使用我的 GO 程序收听传入的 MIDI 消息。但是,我无法让它工作。

我试过使用 https://github.com/gomidi/midi 等 midi 库,但无法正常工作。找不到示例,文档对我来说也不清楚。

package main

import (
    "fmt"
    "io"

    "github.com/gomidi/midi"
    . "github.com/gomidi/midi/midimessage/channel" // (Channel Messages)
    "github.com/gomidi/midi/midimessage/realtime"
    "github.com/gomidi/midi/midireader"
)

func main() {
    var input io.Reader

    rthandler := func(m realtime.Message) {
        fmt.Printf("Realtime: %s\n", m)
    }

    rd := midireader.New(input, rthandler)

    var m midi.Message
    var err error

    for {
        m, err = rd.Read()

        // breaking at least with io.EOF
        if err != nil {
            break
        }

        // inspect
        fmt.Println(m)

        switch v := m.(type) {
        case NoteOn:
            fmt.Printf("NoteOn at channel %v: key: %v velocity: %v\n", v.Channel(), v.Key(), v.Velocity())
        case NoteOff:
            fmt.Printf("NoteOff at channel %v: key: %v\n", v.Channel(), v.Key())
        }

    }

    if err != io.EOF {
        panic("error: " + err.Error())
    }
}

我的目标是能够读取(仅在收到 MIDI 消息时打印)MIDI 输入以进行进一步处理。

提前致谢

这是当前版本 gitlab.com/gomidi/midi 的工作示例(也可以查看 gitlab.com/gomidi/midi/examples)。

package main

import (
    "fmt"

    "time"

    "gitlab.com/gomidi/midi"
    . "gitlab.com/gomidi/midi/midimessage/channel" // (Channel Messages)
    "gitlab.com/gomidi/midi/reader"
    "gitlab.com/gomidi/rtmididrv"
)

// This example reads from the first input port
func main() {
    drv, err := rtmididrv.New()
    must(err)

    // make sure to close the driver at the end
    defer drv.Close()

    ins, err := drv.Ins()
    must(err)

    // takes the first input
    in := ins[0]

    fmt.Printf("opening MIDI Port %v\n", in)
    must(in.Open())

    defer in.Close()

    // to disable logging, pass mid.NoLogger() as option
    rd := reader.New(
        reader.NoLogger(),
        // print every message
        reader.Each(func(pos *reader.Position, msg midi.Message) {

            // inspect
            fmt.Println(msg)

            switch v := msg.(type) {
            case NoteOn:
                fmt.Printf("NoteOn at channel %v: key: %v velocity: %v\n", v.Channel(), v.Key(), v.Velocity())
            case NoteOff:
                fmt.Printf("NoteOff at channel %v: key: %v\n", v.Channel(), v.Key())
            }
        }),
    )

    // listen for MIDI
    err = rd.ListenTo(in)
    must(err)

    time.Sleep(10 * time.Second)
    err = in.StopListening()
    must(err)
    fmt.Printf("closing MIDI Port %v\n", in)
}

func must(err error) {
    if err != nil {
        panic(err.Error())
    }
}