portmidi

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

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

Go to latest
Published: Oct 20, 2020 License: Apache-2.0 Imports: 7 Imported by: 71

README

portmidi

Want to output to an MIDI device or listen your MIDI device as an input? This package contains Go bindings for PortMidi. libportmidi (v. 217) is required as a dependency, it's available via apt-get and brew.

apt-get install libportmidi-dev
# or
brew install portmidi

Or, alternatively you can download the source and build it by yourself. See the instructions on PortMidi homepage.

In order to start, go get this repository:

go get github.com/rakyll/portmidi

Usage

Initialize
portmidi.Initialize()
About MIDI Devices
portmidi.CountDevices() // returns the number of MIDI devices
portmidi.Info(deviceID) // returns info about a MIDI device
portmidi.DefaultInputDeviceID() // returns the ID of the system default input
portmidi.DefaultOutputDeviceID() // returns the ID of the system default output
Write to a MIDI Device
out, err := portmidi.NewOutputStream(deviceID, 1024, 0)
if err != nil {
    log.Fatal(err)
}

// note on events to play C major chord
out.WriteShort(0x90, 60, 100)
out.WriteShort(0x90, 64, 100)
out.WriteShort(0x90, 67, 100)

// notes will be sustained for 2 seconds
time.Sleep(2 * time.Second)

// note off events
out.WriteShort(0x80, 60, 100)
out.WriteShort(0x80, 64, 100)
out.WriteShort(0x80, 67, 100)

out.Close()
Read from a MIDI Device
in, err := portmidi.NewInputStream(deviceID, 1024)
if err != nil {
    log.Fatal(err)
}
defer in.Close()

events, err := in.Read(1024)
if err != nil {
    log.Fatal(err)
}

// alternatively you can filter the input to listen
// only a particular set of channels
in.SetChannelMask(portmidi.Channel(1) | portmidi.Channel.(2))
in.Read(1024) // will retrieve events from channel 1 and 2

// or alternatively listen events
ch := in.Listen()
event := <-ch
Cleanup

Cleanup your input and output streams once you're done. Likely to be called on graceful termination.

portmidi.Terminate()

Documentation

Overview

Package portmidi provides PortMidi bindings.

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	ErrMaxBuffer         = errors.New("portmidi: max event buffer size is 1024")
	ErrMinBuffer         = errors.New("portmidi: min event buffer size is 1")
	ErrInputUnavailable  = errors.New("portmidi: input is unavailable")
	ErrOutputUnavailable = errors.New("portmidi: output is unavailable")
	ErrSysExOverflow     = errors.New("portmidi: SysEx message overflowed")
)

Functions

func CountDevices

func CountDevices() int

CountDevices returns the number of MIDI devices.

func Initialize

func Initialize() error

Initialize initializes the portmidi. Needs to be called before making any other call from the portmidi package. Once portmidi package is no longer required, Terminate should be called to free the underlying resources.

func Terminate

func Terminate() error

Terminate terminates and cleans up the midi streams.

Types

type Channel

type Channel int

Channel represent a MIDI channel. It should be between 1-16.

type DeviceID

type DeviceID int

DeviceID is a MIDI device ID.

func DefaultInputDeviceID

func DefaultInputDeviceID() DeviceID

DefaultInputDeviceID returns the default input device's ID.

func DefaultOutputDeviceID

func DefaultOutputDeviceID() DeviceID

DefaultOutputDeviceID returns the default output device's ID.

type DeviceInfo

type DeviceInfo struct {
	Interface         string
	Name              string
	IsInputAvailable  bool
	IsOutputAvailable bool
	IsOpened          bool
}

DeviceInfo provides info about a MIDI device.

func Info

func Info(deviceID DeviceID) *DeviceInfo

Info returns the device info for the device indentified with deviceID. If deviceID is out of range, Info returns nil.

type Event

type Event struct {
	Timestamp Timestamp
	Status    int64
	Data1     int64
	Data2     int64
	SysEx     []byte
}

Event represents a MIDI event.

type Stream

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

Stream represents a portmidi stream.

func NewInputStream

func NewInputStream(id DeviceID, bufferSize int64) (stream *Stream, err error)

NewInputStream initializes a new input stream.

func NewOutputStream

func NewOutputStream(id DeviceID, bufferSize int64, latency int64) (stream *Stream, err error)

NewOutputStream initializes a new output stream.

func (*Stream) Abort

func (s *Stream) Abort() error

Abort aborts the MIDI stream.

func (*Stream) Close

func (s *Stream) Close() error

Close closes the MIDI stream.

func (*Stream) Listen

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

Listen input stream for MIDI events.

func (*Stream) Poll

func (s *Stream) Poll() (bool, error)

Poll reports whether there is input available in the stream.

Example
package main

import (
	"fmt"
	"log"

	"github.com/rakyll/portmidi"
)

func main() {
	in, err := portmidi.NewInputStream(portmidi.DefaultInputDeviceID(), 1024)
	if err != nil {
		log.Fatal(err)
	}

	result, err := in.Poll()
	if err != nil {
		log.Fatal(err)
	}

	if result {
		fmt.Println("New messages in the queue!")
	} else {
		fmt.Println("No new messages in the queue :(")
	}
}
Output:

func (*Stream) Read

func (s *Stream) Read(max int) (events []Event, err error)

Reads from the input stream, the max number events to be read are determined by max.

func (*Stream) ReadSysExBytes

func (s *Stream) ReadSysExBytes(max int) ([]byte, error)

ReadSysExBytes reads 4*max sysex bytes from the input stream.

Deprecated. Using this API may cause a loss of buffered data. It is preferable to use Read() and inspect the Event.SysEx field to detect SysEx messages.

Example
package main

import (
	"fmt"
	"log"

	"github.com/rakyll/portmidi"
)

func main() {
	in, err := portmidi.NewInputStream(portmidi.DefaultInputDeviceID(), 1024)
	if err != nil {
		log.Fatal(err)
	}

	msg, err := in.Read(1024)
	if err != nil {
		log.Fatal(err)
	}

	for i, b := range msg {
		fmt.Printf("SysEx message byte %d = %02x\n", i, b)
	}
}
Output:

func (*Stream) SetChannelMask

func (s *Stream) SetChannelMask(mask int) error

SetChannelMask filters incoming stream based on channel. In order to filter from more than a single channel, or multiple channels. s.SetChannelMask(Channel(1) | Channel(10)) will both filter input from channel 1 and 10.

func (*Stream) Write

func (s *Stream) Write(events []Event) error

Write writes a buffer of MIDI events to the output stream.

func (*Stream) WriteShort

func (s *Stream) WriteShort(status int64, data1 int64, data2 int64) error

WriteShort writes a MIDI event of three bytes immediately to the output stream.

Example
package main

import (
	"log"
	"time"

	"github.com/rakyll/portmidi"
)

func main() {
	out, err := portmidi.NewOutputStream(portmidi.DefaultOutputDeviceID(), 1024, 0)
	if err != nil {
		log.Fatal(err)
	}

	// Send "note on" events to play C major chord.
	out.WriteShort(0x90, 60, 100)
	out.WriteShort(0x90, 64, 100)
	out.WriteShort(0x90, 67, 100)

	// Notes will be sustained for 2 seconds.
	time.Sleep(2 * time.Second)

	// Note off events.
	out.WriteShort(0x80, 60, 100)
	out.WriteShort(0x80, 64, 100)
	out.WriteShort(0x80, 67, 100)

	out.Close()
}
Output:

func (*Stream) WriteSysEx

func (s *Stream) WriteSysEx(when Timestamp, msg string) error

WriteSysEx writes a system exclusive MIDI message given as a string of hexadecimal characters to the output stream. The string must only consist of hex digits (0-9A-F) and optional spaces. This function is case-insenstive.

Example
package main

import (
	"log"

	"github.com/rakyll/portmidi"
)

func main() {
	out, err := portmidi.NewOutputStream(portmidi.DefaultOutputDeviceID(), 1024, 0)
	if err != nil {
		log.Fatal(err)
	}

	if err = out.WriteSysEx(portmidi.Time(), "F0 0A 0A 1B 00 7F 30 F7"); err != nil {
		log.Fatal(err)
	}
}
Output:

func (*Stream) WriteSysExBytes

func (s *Stream) WriteSysExBytes(when Timestamp, msg []byte) error

WriteSysExBytes writes a system exclusive MIDI message given as a []byte to the output stream.

Example
package main

import (
	"log"

	"github.com/rakyll/portmidi"
)

func main() {
	out, err := portmidi.NewOutputStream(portmidi.DefaultOutputDeviceID(), 1024, 0)
	if err != nil {
		log.Fatal(err)
	}

	if err = out.WriteSysExBytes(portmidi.Time(), []byte{0xF0, 0x0A, 0x0A, 0x1B, 0x00, 0x7F, 0x30, 0xF7}); err != nil {
		log.Fatal(err)
	}
}
Output:

type Timestamp

type Timestamp int64

func Time

func Time() Timestamp

Time returns the portmidi timer's current time.

Jump to

Keyboard shortcuts

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