midi

package
v0.0.0-...-028b308 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 25, 2018 License: Apache-2.0 Imports: 3 Imported by: 11

Documentation

Overview

Package midi allows you to listen to incoming MIDI messages.

Warning! This is not a feature-complete MIDI implementation. MIDI system messages are ignored with the exception of CLOCK, START, and STOP messages.

Example

If you already have a main event loop, do this:

// Launch the MIDI reader thread and get the channel it uses to deliver incoming messages
midiMessageChan := midi.GetMidiMessageStream("/dev/midi1")

// Create a persistent object which knows the current MIDI state
// This includes the current volumes of all notes (will be 0 for non-playing notes)
// and the current value of all controllers.
midiState := midi.MidiState{}

// Your main event loop
for {
    // Nonblockingly get all the MIDI messages that have come in since we last checked
    // and use them to update the MIDI state
    midiState.UpdateStateFromChannel(midiMessageChan)

    // Do things with the MIDI data
    if midiState.KeyVolumes[60] > 0 {
        fmt.Println("Key 60 is held down right now")
    }
}

For more details on MIDI:

http://www.midi.org/techspecs/midimessages.php

https://en.wikipedia.org/wiki/MIDI_timecode#Quarter-frame_messages

Index

Constants

View Source
const (
	LPD8_PAD1 byte = 36 + iota
	LPD8_PAD2 byte = 36 + iota
	LPD8_PAD3 byte = 36 + iota
	LPD8_PAD4 byte = 36 + iota
	LPD8_PAD5 byte = 36 + iota
	LPD8_PAD6 byte = 36 + iota
	LPD8_PAD7 byte = 36 + iota
	LPD8_PAD8 byte = 36 + iota
)

AKAI LPD8 pad notes

View Source
const (
	LPD8_KNOB1 byte = 1 + iota
	LPD8_KNOB2 byte = 1 + iota
	LPD8_KNOB3 byte = 1 + iota
	LPD8_KNOB4 byte = 1 + iota
	LPD8_KNOB5 byte = 1 + iota
	LPD8_KNOB6 byte = 1 + iota
	LPD8_KNOB7 byte = 1 + iota
	LPD8_KNOB8 byte = 1 + iota
)

AKAI LPD8 knob controllers

View Source
const (
	NOTE_OFF         byte = 0x80
	NOTE_ON          byte = 0x90
	AFTERTOUCH       byte = 0xa0
	CONTROLLER       byte = 0xb0
	PROGRAM_CHANGE   byte = 0xc0
	CHANNEL_PRESSURE byte = 0xd0
	PITCH_BEND       byte = 0xe0
	SYSTEM           byte = 0xf0
)

kinds of MIDI messages

View Source
const (
	CLOCK byte = 8
	START byte = 10
	STOP  byte = 12
)

special channel numbers for SYSTEM messages

View Source
const RETRY_WAIT = 2 // seconds to wait before retrying opening midi device file

Variables

This section is empty.

Functions

func GetMidiMessageStream

func GetMidiMessageStream(path string) chan *MidiMessage

Start some threads which will read and parse incoming MIDI messages in the background. Return a channel which emits pointers to MidiMessage structs. "path" should be the path to the midi device, e.g. "/dev/midi1". If the path can't be opened, it will keep retrying once a second forever until it succeeds.

func MidiStreamParserThread

func MidiStreamParserThread(inCh chan byte, outCh chan *MidiMessage)

Read a stream of raw MIDI bytes on inCh, parse them into *MidiMessage structs, and send over outCh. It accepts CLOCK, START, and STOP system messages but other system messages are ignored.

Types

type MidiMessage

type MidiMessage struct {
	Kind    byte // one of the constants above
	Channel byte // either a channel number of one of the special channel constants CLOCK, START, STOP
	Key     byte // key, controller, instrument, or pitch bend lsb
	Value   byte // velocity, touch, controller value, channel pressure, or pitch bend msb
}

func GetAvailableMidiMessages

func GetAvailableMidiMessages(midiMessageChan chan *MidiMessage) []*MidiMessage

Pull all the available MidiMessages out of the channel without blocking. Requires a channel with a buffer length greater than zero. This can deadlock if used by more than one goroutine at a time pulling on the same channel.

func (*MidiMessage) String

func (m *MidiMessage) String() string

Convert the MidiMessage to a human-readable string so it can be printed

type MidiState

type MidiState struct {
	KeyVolumes         [128]byte      // values from 0 to 127
	ControllerValues   [128]byte      // values from 0 to 127
	RecentMidiMessages []*MidiMessage // midi messages from the most recent call to UpdateStateXXX()
}

Keeps track of the current state of the keys and controllers.

func (*MidiState) UpdateStateFromChannel

func (midiState *MidiState) UpdateStateFromChannel(midiMessageChan chan *MidiMessage)

Given a channel of MidiMessages, read all the messages that are available right now and update the MidiState object. Requires a channel that has a buffer length greater than zero.

func (*MidiState) UpdateStateFromSlice

func (midiState *MidiState) UpdateStateFromSlice(midiMessages []*MidiMessage)

Given a slice of MidiMessages, update the MidiState object. Note that the MidiState object will keep a pointer to the midiMessages object you provide here (as MidiState.RecentMidiMessages).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL