portmidi

package module
v0.0.0-...-a2cf512 Latest Latest
Warning

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

Go to latest
Published: Sep 5, 2017 License: MIT Imports: 3 Imported by: 2

README

portmidi GoDoc

Package portmidi provides Go bindings for PortMIDI from the PortMedia set of libraries. PortMedia offers free, cross-platform, open-source I/O libraries for digital media including MIDI, video, and audio.

All the binding code for the pm package has automatically been generated with rules defined in pm.yml. The wrapping package portmidi has been done by hand and leverages channels for MIDI event streaming.

Usage

$ brew install portmidi
(or use your package manager)

$ go get github.com/xlab/portmidi

Examples

MIDIPipe

midipipe is a simple Go program that redirects all the events it gets from a MIDI input device to the specified MIDI output device. You can specify route by device name (see example) or by its ID.

The app requires minimum two devices to operate properly, but note that a single hardware piece can act both as input and output device, so by "devices" I mean logical I/O streams.

$ brew install portmidi
$ go get github.com/xlab/portmidi/example/midipipe

$ midipipe -in "Arturia BeatStep" -out "OP-1 Midi Device"

main.go:35: [INFO] total MIDI devices: 4
main.go:50: [INFO] available inputs: map[Arturia BeatStep:1 OP-1 Midi Device:0]
main.go:51: [INFO] available outputs: map[OP-1 Midi Device:2 Arturia BeatStep:3]

main.go:56: [INFO] input device id=1 .
├── [CoreMIDI]  Interface
├── [Arturia BeatStep]  Name
├── [true]  IsInputAvailable
└── [false]  IsOutputAvailable
main.go:65: [INFO] output device id=2 .
├── [CoreMIDI]  Interface
├── [OP-1 Midi Device]  Name
├── [false]  IsInputAvailable
└── [true]  IsOutputAvailable

main.go:80: [DBG] rate 1 minute 100.14564014611834
main.go:81: [DBG] rate 5 minute 51.93229225191669
main.go:82: [DBG] rate mean 134.09919032344553

main.go:80: [DBG] rate 1 minute 65.02414338183416
main.go:81: [DBG] rate 5 minute 51.98104984601001
main.go:82: [DBG] rate mean 93.71848260518783
^Cmain.go:72: bye!
Vocoder

vocoder is an implementation of a simple vocoder in Go. It reads your voice using PortAudio, reads note-on events from your MIDI device using PortMIDI, and plays the altered voice back using PortAudio. Have fun.

$ brew install portaudio portmidi
$ go get github.com/xlab/portmidi/example/vocoder

$ vocoder -in "Arturia BeatStep"
main.go:43: [INFO] available inputs: map[IAC Driver Bus 1:0 Arturia BeatStep:1]
main.go:46: Using Arturia BeatStep (via CoreMIDI)
main.go:62: note 63 (311.127Hz)
main.go:62: note 62 (293.665Hz)
main.go:62: note 65 (349.228Hz)
main.go:62: note 73 (554.365Hz)
main.go:62: note 66 (369.994Hz)
main.go:62: note 60 (261.626Hz)
^C
Rebuilding the package

You will need to get the cgogen tool installed first.

$ git clone https://github.com/xlab/portmidi && cd portmidi
$ make clean
$ make

License

All the code except when stated otherwise is licensed under the MIT license.

Documentation

Overview

Package portmidi provides Go bindings for PortMIDI from the PortMedia set of libraries.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CountDevices

func CountDevices() int

CountDevices gets devices count, ids range from 0 to CountDevices()-1.

func GetHostError

func GetHostError() error

GetHostError translates portmidi host error into human readable message.

func Initialize

func Initialize() error

Initialize is the library initialisation function: call this before using portmidi.

func Terminate

func Terminate() error

Terminate is the library termination function: call this after using portmidi.

Types

type ChannelMask

type ChannelMask int32

func Channel

func Channel(ch int) ChannelMask

Channel sets a channel mask to pass to a stream. Multiple channels should be OR'ed together Channel(1) | Channel(2). Note that channels are numbered 0 to 15 (not 1 to 16). All channels are allowed by default.

type DeviceID

type DeviceID pm.DeviceID

func DefaultInputDeviceID

func DefaultInputDeviceID() (DeviceID, bool)

DefaultInputDeviceID returns the default input device ID or ok=false if there are no devices.

func DefaultOutputDeviceID

func DefaultOutputDeviceID() (DeviceID, bool)

DefaultOutputDeviceID returns the default output device ID or ok=false if there are no devices.

type DeviceInfo

type DeviceInfo struct {
	// Interface specifies underlying MIDI API, e.g. MMSystem or DirectX.
	Interface string
	// Name is a device name, e.g. USB MidiSport 1x1
	Name string
	// IsInputAvailable true iff input is available.
	IsInputAvailable bool
	// IsOutputAvailable true iff output is available.
	IsOutputAvailable bool
}

func GetDeviceInfo

func GetDeviceInfo(id DeviceID) *DeviceInfo

GetDeviceInfo returns device info for the provided device ID, or nil if ID is out of range.

type Event

type Event struct {
	Timestamp int32
	Message   Message
	SysExData []byte
}

type Filter

type Filter int32
const (
	// FilterActive filters active sensing messages (0xFE).
	FilterActive Filter = (1 << 0x0E)
	// FilterSysEx filters system exclusive messages (0xF0).
	FilterSysEx Filter = (1 << 0x00)
	// FilterClock filters MIDI clock messages (0xF8).
	FilterClock Filter = (1 << 0x08)
	// FilterPlay filters play messages (start 0xFA, stop 0xFC, continue 0xFB).
	FilterPlay Filter = ((1 << 0x0A) | (1 << 0x0C) | (1 << 0x0B))
	// FilterTick filters tick messages.
	FilterTick Filter = (1 << 0x09)
	// FilterFd filters undefined FD messages.
	FilterFD Filter = (1 << 0x0D)
	// FilterUndefined filters undefined real-time messages.
	FilterUndefined Filter = FilterFD
	// FilterReset filters reset messages.
	FilterReset Filter = (1 << 0x0F)
	// FilterRealtime filters all real-time messages.
	FilterRealtime Filter = (FilterActive | FilterSysEx | FilterClock | FilterPlay | FilterUndefined | FilterReset | FilterTick)
	// FilterNote filters note-on and note-off (0x90-0x9F and 0x80-0x8F).
	FilterNote Filter = ((1 << 0x19) | (1 << 0x18))
	// FilterChannelAftertouch filters channel aftertouch (most midi controllers use this) (0xD0-0xDF).
	FilterChannelAftertouch Filter = (1 << 0x1D)
	// FilterPolyAftertouch filters per-note aftertouch (0xA0-0xAF).
	FilterPolyAftertouch Filter = (1 << 0x1A)
	// FilterAftertouch filters both channel and poly aftertouch.
	FilterAftertouch Filter = (FilterChannelAftertouch | FilterPolyAftertouch)
	// FilterProgram filters program changes (0xC0-0xCF).
	FilterProgram Filter = (1 << 0x1C)
	// FilterControl filters control changes (CC's) (0xB0-0xBF).
	FilterControl Filter = (1 << 0x1B)
	// FilterPitchbend filters pitch bends (0xE0-0xEF).
	FilterPitchbend Filter = (1 << 0x1E)
	// FilterMTC filters MIDI Time Code (0xF1).
	FilterMTC Filter = (1 << 0x01)
	// FilterSongPosition filters song position (0xF2).
	FilterSongPosition Filter = (1 << 0x02)
	// FilterSongSelect filters song select (0xF3).
	FilterSongSelect Filter = (1 << 0x03)
	// FilterTune filters tuning request (0xF6).
	FilterTune Filter = (1 << 0x06)
	// FilterSystemCommon filters all system common messages (mtc, song position, song select, tune request).
	FilterSystemCommon Filter = (FilterMTC | FilterSongPosition | FilterSongSelect | FilterTune)
)

func (*Filter) Join

func (f *Filter) Join(fs ...Filter)

type Message

type Message int32

func NewMessage

func NewMessage(status, data1, data2 byte) Message

NewMessage encodes a short MIDI message into a 32-bit word. If data1 and/or data2 are not present, use zero.

func (Message) Data1

func (m Message) Data1() byte

func (Message) Data2

func (m Message) Data2() byte

func (Message) Status

func (m Message) Status() byte

type Stream

type Stream struct {
	// contains filtered or unexported fields
}

func NewInputStream

func NewInputStream(id DeviceID, bufferSize int,
	channels ChannelMask, filters ...Filter) (*Stream, error)

NewInputStream opens device for the input. The buffersize specifies the number of input events to be buffered waiting to be read.

func NewOutputStream

func NewOutputStream(id DeviceID, bufferSize, latency int,
	channels ChannelMask, filters ...Filter) (*Stream, error)

NewOutputStream opens device for the input. The buffersize specifies the number of output events to be buffered waiting for output. (In some cases -- see below -- PortMidi does not buffer output at all and merely passes data to a lower-level API, in which case buffersize is ignored.)

latency is the delay in milliseconds applied to timestamps to determine when the output should actually occur. (If latency is < 0, 0 is assumed.) If latency is zero, timestamps are ignored and all output is delivered immediately. If latency is greater than zero, output is delayed until the message timestamp plus the latency. (NOTE: the time is measured relative to the time source indicated by time_proc. Timestamps are absolute, not relative delays or offsets.) In some cases, PortMidi can obtain better timing than your application by passing timestamps along to the device driver or hardware. Latency may also help you to synchronize midi data to audio data by matching midi latency to the audio buffer latency.

func (*Stream) Close

func (s *Stream) Close() error

Close closes a midi stream, flushing any pending buffers.

func (*Stream) HasHostError

func (s *Stream) HasHostError() bool

HasHostError tests whether stream has a pending host error. Normally, the client finds out about errors through returned error codes, but some errors can occur asynchronously where the client does not explicitly call a function, and therefore cannot receive an error code.

func (*Stream) Sink

func (s *Stream) Sink() chan<- Event

func (*Stream) Source

func (s *Stream) Source() <-chan Event

Directories

Path Synopsis
example
Package pm provides Go bindings for portmidi.
Package pm provides Go bindings for portmidi.

Jump to

Keyboard shortcuts

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