Skip to content
Snippets Groups Projects
Select Git revision
  • master default protected
  • tools/midicat/v0.8.2
  • v2.2.19
  • drivers/rtmididrv/imported/rtmidi/v0.9.5
  • drivers/rtmididrv/v0.9.5
  • tools/midicat/v0.8.0
  • tools/midicat/v0.8.1
  • v2.2.18
  • drivers/rtmididrv/imported/rtmidi/v0.9.4
  • drivers/rtmididrv/v0.9.4
  • v2.2.17
  • drivers/rtmididrv/imported/rtmidi/v0.9.3
  • drivers/rtmididrv/v0.9.3
  • v2.2.16
  • drivers/rtmididrv/imported/rtmidi/v0.9.2
  • drivers/rtmididrv/v0.9.2
  • v2.2.15
  • v2.2.14
  • tools/hyperarp/v0.0.23
  • tools/midicat/v0.7.1
  • tools/midispy/v2.1.1
21 results

midi

  • Clone with SSH
  • Clone with HTTPS
  • user avatar
    Marc Rene Arns authored
    a99961b0
    History

    midi

    Modular library for reading and writing of MIDI messages with Go.

    Build Status Travis/Linux Build Status AppVeyor/Windows Coverage Status Go Report Documentation

    This package is meant for users that have some knowledge of the MIDI standards. Beginners, and people on the run might want to look at the porcelain package https://gitlab.com/gomidi/mid.

    Status

    stable

    • Go version: >= 1.10
    • OS/architectures: everywhere Go runs (tested on Linux and Windows).

    Installation

    go get gitlab.com/gomidi/midi/...

    Documentation

    see http://godoc.org/gitlab.com/gomidi/midi

    Features

    • implementation of complete MIDI standard (live and SMF data)
    • reading and optional writing with "running status"
    • seemless integration with io.Reader and io.Writer
    • allows the reuse of same libraries for live writing and writing to SMF files
    • provide building blocks for other MIDI libraries and applications
    • stable API
    • no dependencies outside the standard library
    • small modular core packages
    • typed Messages
    • pure Go library (no C, no assembler)

    Non-Goals

    • constructing of MIDI time code messages
    • Multidimensional Polyphonic Expression (MPE)
    • dealing with the inner structure of sysex messages
    • connection to MIDI devices (for this combine it with https://gitlab.com/gomidi/connect)
    • CLI tools

    Usage / Example

    package main
    
    import (
        "bytes"
        "fmt"
        . "gitlab.com/gomidi/midi/midimessage/channel"
        "gitlab.com/gomidi/midi/midimessage/realtime"
        "gitlab.com/gomidi/midi/midireader"
        "gitlab.com/gomidi/midi/midiwriter"
        "io"
        "gitlab.com/gomidi/midi"
    )
    
    func main() {
        var bf bytes.Buffer
    
        wr := midiwriter.New(&bf)
        wr.Write(Channel2.Pitchbend(5000))
        wr.Write(Channel2.NoteOn(65, 90))
        wr.Write(realtime.Reset)
        wr.Write(Channel2.NoteOff(65))
    
        rthandler := func(m realtime.Message) {
            fmt.Printf("Realtime: %s\n", m)
        }
    
        rd := midireader.New(bytes.NewReader(bf.Bytes()), 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())
        }
    
        // Output:
        // channel.Pitchbend channel 2 value 5000 absValue 13192
        // channel.NoteOn channel 2 key 65 velocity 90
        // NoteOn at channel 2: key: 65 velocity: 90
        // Realtime: Reset
        // channel.NoteOff channel 2 key 65
        // NoteOff at channel 2: key: 65
    }
    

    Modularity

    This package is divided into small subpackages, so that you only need to import what you really need. This keeps packages and dependencies small, better testable and should result in a smaller memory footprint which should help smaller devices.

    For reading and writing of live and SMF MIDI data io.Readers are accepted as input and io.Writers as output. Furthermore there are common interfaces for live and SMF MIDI data handling: midi.Reader and midi.Writer. The typed MIDI messages used in each case are the same.

    To connect with MIDI libraries expecting and returning plain bytes (e.g. over the wire), use midiio subpackage.

    Perfomance

    On my laptop, writing noteon and noteoff ("live")

    BenchmarkSameChannel            123 ns/op  12 B/op  3 allocs/op
    BenchmarkAlternatingChannel     123 ns/op  12 B/op  3 allocs/op
    BenchmarkRunningStatusDisabled  110 ns/op  12 B/op  3 allocs/op

    On my laptop, reading noteon and noteoff ("live") ("Samechannel" makes use of running status byte).

    BenchmarkSameChannel            351 ns/op  12 B/op  7 allocs/op
    BenchmarkAlternatingChannel     425 ns/op  14 B/op  9 allocs/op

    License

    MIT (see LICENSE file)

    Credits

    Inspiration and low level code for MIDI reading (see internal midilib package) came from the http://github.com/afandian/go-midi package of Joe Wass which also helped as a starting point for the reading of SMF files.

    Alternatives

    Matt Aimonetti is also working on MIDI inside https://github.com/mattetti/audio but I didn't try it.