mid

package module
v0.20.3 Latest Latest
Warning

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

Go to latest
Published: Oct 26, 2019 License: MIT Imports: 19 Imported by: 1

README

mid

Porcelain library for reading and writing MIDI and SMF (Standard MIDI File)

Based on https://github.com/gomidi/midi.

Build Status Travis/Linux Coverage Status Go Report Documentation

Notice - Moved

Development has moved to GitLab https://gitlab.com/gomidi. It is recommended to use the code there instead, as the repos at Gitlab contains newer fixes, and some import references contained in the github repo may be broken

Description

Package mid provides an easy abstraction for reading and writing of "live" MIDI and SMF (Standard MIDI File) data.

MIDI data could be written the following ways:

  • NewWriter is used to write "live" MIDI to an io.Writer.
  • NewSMF is used to write SMF MIDI to an io.Writer.
  • NewSMFFile is used to write a complete SMF file.
  • WriteTo writes "live" MIDI to an connect.Out, aka MIDI out port

To read, create a Reader and attach callbacks to it. Then MIDI data could be read the following ways:

  • Reader.Read reads "live" MIDI from an io.Reader.
  • Reader.ReadSMF reads SMF MIDI from an io.Reader.
  • Reader.ReadSMFFile reads a complete SMF file.
  • Reader.ReadFrom reads "live" MIDI from an connect.In, aka MIDI in port

For a simple example with "live" MIDI and io.Reader and io.Writer see the example below.

To connect with the MIDI ports of your computer (via connect.In and connect.Out), use it with one of the driver packages for rtmidi and portaudio at https://github.com/gomidi/connect.

There you can find a simple example how to do it.

Example

We use an io.Writer to write to and io.Reader to read from. They are connected by the same io.Pipe.

package main

import (
    "fmt"
    "github.com/gomidi/mid"
    "io"
    "time"
)

// callback for note on messages
func noteOn(p *mid.Position, channel, key, vel uint8) {
    fmt.Printf("NoteOn (ch %v: key %v vel: %v)\n", channel, key, vel)
}

// callback for note off messages
func noteOff(p *mid.Position, channel, key, vel uint8) {
    fmt.Printf("NoteOff (ch %v: key %v)\n", channel, key)
}

func main() {
    fmt.Println()

    // to disable logging, pass mid.NoLogger() as option
    rd := mid.NewReader()

    // set the functions for the messages you are interested in
    rd.Msg.Channel.NoteOn = noteOn
    rd.Msg.Channel.NoteOff = noteOff

    // to allow reading and writing concurrently in this example
    // we need a pipe
    piperd, pipewr := io.Pipe()

    go func() {
        wr := mid.NewWriter(pipewr)
        wr.SetChannel(11) // sets the channel for the next messages
        wr.NoteOn(120, 50)
        time.Sleep(time.Second) // let the note ring for 1 sec
        wr.NoteOff(120)
        pipewr.Close() // finishes the writing
    }()

    for {
        if rd.Read(piperd) == io.EOF {
            piperd.Close() // finishes the reading
            break
        }
    }

    // Output:
    // channel.NoteOn channel 11 key 120 velocity 50
    // NoteOn (ch 11: key 120 vel: 50)
    // channel.NoteOff channel 11 key 120
    // NoteOff (ch 11: key 120)
}

Status

API mostly stable and complete

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

Installation

It is recommended to use Go 1.11 with module support ($GO111MODULE=on).

go get -d github.com/gomidi/mid/...

License

MIT (see LICENSE file)

Documentation

Overview

Package mid provides an easy abstraction for reading and writing of "live" MIDI and SMF (Standard MIDI File) data.

MIDI data could be written the following ways:

  • WriteTo writes "live" MIDI to an OutConnection, aka MIDI out port
  • NewWriter is used to write "live" MIDI to an io.Writer.
  • NewSMF is used to write SMF MIDI to an io.Writer.
  • NewSMFFile is used to write a complete SMF file.

To read, create a Reader and attach callbacks to it. Then MIDI data could be read the following ways:

  • Reader.ReadFrom reads "live" MIDI from an InConnection, aka MIDI in port
  • Reader.Read reads "live" MIDI from an io.Reader.
  • Reader.ReadSMF reads SMF MIDI from an io.Reader.
  • Reader.ReadSMFFile reads a complete SMF file.

For a simple example with "live" MIDI and io.Reader and io.Writer see examples/simple/simple_test.go.

To connect with the MIDI ports of your computer (via InConnection and OutConnection), use it with the adapter packages for rtmidi and portaudio at https://github.com/gomidi/connect.

There you can find a simple example how to do it.

Example
package main

import (
	"bytes"
	"fmt"
	"io"
	"time"

	"github.com/gomidi/midi/smf"
)

// makeSMF makes a SMF
func makeSMF() io.Reader {
	var bf bytes.Buffer
	wr := NewSMF(&bf, 1 /* number of tracks */)
	wr.TempoBPM(160 /* beats per minute */)
	wr.SetChannel(2 /* valid: 0-15 */)
	wr.NoteOn(65 /* key */, 90 /* velocity */)
	wr.SetDelta(4000 /* ticks */)
	wr.NoteOff(65 /* key */)
	wr.EndOfTrack() // required at the end of a track
	return bytes.NewReader(bf.Bytes())
}

// roundSec is a helper to round the duration to seconds
func roundSec(d time.Duration) time.Duration {
	return time.Second * time.Duration((d.Nanoseconds() / 1000000000))
}

type example struct {
	ticks smf.MetricTicks
	bpm   float64
	start time.Time
}

// SMFHeader tracks the ticks from the SMF file
func (e *example) SMFHeader(head smf.Header) {
	// here we ignore that the timeformat could also be SMPTE
	e.ticks = head.TimeFormat.(smf.MetricTicks)
}

// Tempo tracks a tempo change
func (e *example) TempoBPM(p Position, bpm float64) {
	e.bpm = bpm
}

// NoteOn responds to note on messages
func (e *example) NoteOn(p *Position, channel, key, vel uint8) {
	fmt.Printf("[%vs] NoteOn at channel %v: key %v velocity: %v\n",
		e.calcDuration(p).Seconds(), channel, key, vel)
}

func (e *example) NoteOff(p *Position, channel, key, vel uint8) {
	fmt.Printf("[%vs] NoteOff at channel %v: key %v velocity: %v\n",
		e.calcDuration(p).Seconds(),
		channel, key, vel)
}

// a helper to calculate the duration for both live and SMF messages
func (e *example) calcDuration(p *Position) (dur time.Duration) {
	// we are in a live setting
	if p == nil {
		dur = roundSec(time.Now().Sub(e.start))
		return
	}

	// here p is not nil - that means we are reading the SMF

	// calculate the time from the timeformat of the SMF file
	// to make it easy, we ignore the possibility that tempo information may be in another track
	// that is read after this track (the SMF spec recommends to write tempo changes to the first track)
	// however, since makeSMF just creates one track, we are safe
	return roundSec(e.ticks.FractionalDuration(e.bpm, uint32(p.AbsoluteTicks)))
}

func main() {
	// This example illustrates how the same handler can be used for live and SMF MIDI messages
	// It also illustrates how live and SMF midi can be written

	rd := NewReader(NoLogger() /* disable default logging*/)

	var ex example
	ex.bpm = 120 // default according to SMF spec

	// setup the callbacks
	rd.SMFHeader = ex.SMFHeader
	rd.Msg.Meta.TempoBPM = ex.TempoBPM
	rd.Msg.Channel.NoteOn = ex.NoteOn
	rd.Msg.Channel.NoteOff = ex.NoteOff

	// handle the smf
	fmt.Println("-- SMF data --")
	rd.ReadSMF(makeSMF())

	// handle the live data
	fmt.Println("-- live data --")

	// we need a pipe to read and write concurrently
	piperd, pipewr := io.Pipe()

	go func() {
		wr := NewWriter(pipewr)

		// reset the time
		ex.start = time.Now()

		wr.SetChannel(11)

		// now write some live data
		wr.NoteOn(120, 50)
		time.Sleep(time.Second * 2)
		wr.NoteOff(120)
		pipewr.Close() // close the pipe we're done writing
	}()

	for {
		if rd.Read(piperd) == io.EOF {
			piperd.Close() // we're done reading
			break
		}
	}

}
Output:

-- SMF data --
[0s] NoteOn at channel 2: key 65 velocity: 90
[1s] NoteOff at channel 2: key 65 velocity: 0
-- live data --
[0s] NoteOn at channel 11: key 120 velocity: 50
[2s] NoteOff at channel 11: key 120 velocity: 0

Index

Examples

Constants

View Source
const LiveResolution = smf.MetricTicks(1920)

LiveResolution is the resolution used for live over the wire reading with Reader.ReadFrom

Variables

This section is empty.

Functions

func NewSMFFile

func NewSMFFile(file string, numtracks uint16, writer func(*SMFWriter) error, options ...smfwriter.Option) error

NewSMFFile creates a new SMF file and allows writer to write to it. The file is guaranteed to be closed when returning. The last track is closed automatically, if needed. It panics if numtracks is == 0.

Types

type Logger

type Logger interface {
	Printf(format string, vals ...interface{})
}

Logger is the inferface used by Reader for logging incoming messages.

type Position added in v0.9.0

type Position struct {

	// Track is the number of the track, starting with 0
	Track int16

	// DeltaTicks is number of ticks that passed since the previous message in the same track
	DeltaTicks uint32

	// AbsoluteTicks is the number of ticks that passed since the beginning of the track
	AbsoluteTicks uint64
}

Position is the position of the event inside a standard midi file (SMF) or since start listening on a connection.

type Reader

type Reader struct {

	// SMFHeader is the callback that gets SMF header data
	SMFHeader func(smf.Header)

	// Msg provides callbacks for MIDI messages
	Msg struct {

		// Each is called for every MIDI message in addition to the other callbacks.
		Each func(*Position, midi.Message)

		// Unknown is called for undefined or unknown messages
		Unknown func(p *Position, msg midi.Message)

		// Meta provides callbacks for meta messages (only in SMF files)
		Meta struct {

			// Copyright is called for the copyright message
			Copyright func(p Position, text string)

			// TempoBPM is called for the tempo (change) message, BPM is fractional
			TempoBPM func(p Position, bpm float64)

			// TimeSigis called for the time signature (change) message
			TimeSig func(p Position, num, denom uint8)

			// Key is called for the key signature (change) message
			Key func(p Position, key uint8, ismajor bool, num_accidentals uint8, accidentals_are_flat bool)

			// Track is called for the track (name) message
			Track func(p Position, name string)

			// Sequence is called for the sequence (name) message
			Sequence func(p Position, name string)

			// SequenceNo is called for the sequence number message
			SequenceNo func(p Position, number uint16)

			// Marker is called for the marker message
			Marker func(p Position, text string)

			// Cuepoint is called for the cuepoint message
			Cuepoint func(p Position, text string)

			// Text is called for the text message
			Text func(p Position, text string)

			// Lyric is called for the lyric message
			Lyric func(p Position, text string)

			// EndOfTrack is called for the end of a track message
			EndOfTrack func(p Position)

			// Device is called for the device port message
			Device func(p Position, name string)

			// Program is called for the program name message
			Program func(p Position, text string)

			// SMPTE is called for the smpte offset message
			SMPTE func(p Position, hour, minute, second, frame, fractionalFrame byte)

			// SequencerData is called for the sequencer specific message
			SequencerData func(p Position, data []byte)

			Deprecated struct {
				// Channel is called for the deprecated MIDI channel message
				Channel func(p Position, channel uint8)

				// Port is called for the deprecated MIDI port message
				Port func(p Position, port uint8)
			}
		}

		// Channel provides callbacks for channel messages
		// They may occur in SMF files and in live MIDI.
		// For live MIDI *Position is nil.
		Channel struct {

			// NoteOn is just called for noteon messages with a velocity > 0.
			// Noteon messages with velocity == 0 will trigger NoteOff with a velocity of 0.
			NoteOn func(p *Position, channel, key, velocity uint8)

			// NoteOff is called for noteoff messages (then the given velocity is passed)
			// and for noteon messages of velocity 0 (then velocity is 0).
			NoteOff func(p *Position, channel, key, velocity uint8)

			// Pitchbend is called for pitch bend messages
			Pitchbend func(p *Position, channel uint8, value int16)

			// ProgramChange is called for program change messages. Program numbers start with 0.
			ProgramChange func(p *Position, channel, program uint8)

			// Aftertouch is called for aftertouch messages  (aka "channel pressure")
			Aftertouch func(p *Position, channel, pressure uint8)

			// PolyAftertouch is called for polyphonic aftertouch messages (aka "key pressure").
			PolyAftertouch func(p *Position, channel, key, pressure uint8)

			// ControlChange deals with control change messages
			ControlChange struct {

				// Each is called for every control change message
				// If RPN or NRPN callbacks are defined, the corresponding control change messages will not
				// be passed to each and the corrsponding RPN/NRPN callback are called.
				Each func(p *Position, channel, controller, value uint8)

				// RPN deals with Registered Program Numbers (RPN) and their values.
				// If the callbacks are set, the corresponding control change messages will not be passed of ControlChange.Each.
				RPN struct {

					// MSB is called, when the MSB of a RPN arrives
					MSB func(p *Position, channel, typ1, typ2, msbVal uint8)

					// LSB is called, when the MSB of a RPN arrives
					LSB func(p *Position, channel, typ1, typ2, lsbVal uint8)

					// Increment is called, when the increment of a RPN arrives
					Increment func(p *Position, channel, typ1, typ2 uint8)

					// Decrement is called, when the decrement of a RPN arrives
					Decrement func(p *Position, channel, typ1, typ2 uint8)

					// Reset is called, when the reset or null RPN arrives
					Reset func(p *Position, channel uint8)
				}

				// NRPN deals with Non-Registered Program Numbers (NRPN) and their values.
				// If the callbacks are set, the corresponding control change messages will not be passed of ControlChange.Each.
				NRPN struct {

					// MSB is called, when the MSB of a NRPN arrives
					MSB func(p *Position, channel uint8, typ1, typ2, msbVal uint8)

					// LSB is called, when the LSB of a NRPN arrives
					LSB func(p *Position, channel uint8, typ1, typ2, msbVal uint8)

					// Increment is called, when the increment of a NRPN arrives
					Increment func(p *Position, channel, typ1, typ2 uint8)

					// Decrement is called, when the decrement of a NRPN arrives
					Decrement func(p *Position, channel, typ1, typ2 uint8)

					// Reset is called, when the reset or null NRPN arrives
					Reset func(p *Position, channel uint8)
				}
			}
		}

		// Realtime provides callbacks for realtime messages.
		// They are only used with "live" MIDI
		Realtime struct {

			// Clock is called for a clock message
			Clock func()

			// Tick is called for a tick message
			Tick func()

			// Activesense is called for a active sense message
			Activesense func()

			// Start is called for a start message
			Start func()

			// Stop is called for a stop message
			Stop func()

			// Continue is called for a continue message
			Continue func()

			// Reset is called for a reset message
			Reset func()
		}

		// SysCommon provides callbacks for system common messages.
		// They are only used with "live" MIDI
		SysCommon struct {

			// Tune is called for a tune request message
			Tune func()

			// SongSelect is called for a song select message
			SongSelect func(num uint8)

			// SPP is called for a song position pointer message
			SPP func(pos uint16)

			// MTC is called for a MIDI timing code message
			MTC func(frame uint8)
		}

		// SysEx provides callbacks for system exclusive messages.
		// They may occur in SMF files and in live MIDI.
		// For live MIDI *Position is nil.
		SysEx struct {

			// Complete is called for a complete system exclusive message
			Complete func(p *Position, data []byte)

			// Start is called for a starting system exclusive message
			Start func(p *Position, data []byte)

			// Continue is called for a continuing system exclusive message
			Continue func(p *Position, data []byte)

			// End is called for an ending system exclusive message
			End func(p *Position, data []byte)

			// Escape is called for an escaping system exclusive message
			Escape func(p *Position, data []byte)
		}
	}
	// contains filtered or unexported fields
}

Reader allows the reading of either "over the wire" MIDI data (via Read) or SMF MIDI data (via ReadSMF or ReadSMFFile).

Before any of the Read* methods are called, callbacks for the MIDI messages of interest need to be attached to the Reader. These callbacks are then invoked when the corresponding MIDI message arrives. They must not be changed while any of the Read* methods is running.

It is possible to share the same Reader for reading of the wire MIDI ("live") and SMF Midi data as long as not more than one Read* method is running at a point in time. However, only channel messages and system exclusive message may be used in both cases. To enable this, the corresponding callbacks receive a pointer to the Position of the MIDI message. This pointer is always nil for "live" MIDI data and never nil when reading from a SMF.

The SMF header callback and the meta message callbacks are only called, when reading data from an SMF. Therefore the Position is passed directly and can't be nil.

System common and realtime message callbacks will only be called when reading "live" MIDI, so they get no Position.

func NewReader

func NewReader(opts ...ReaderOption) *Reader

NewReader returns a new Reader

func (*Reader) Duration added in v0.9.7

func (r *Reader) Duration(deltaticks uint32) time.Duration

Duration returns the duration for the given delta ticks, respecting the current tempo

func (*Reader) Read

func (r *Reader) Read(src io.Reader) (err error)

Read reads midi messages from src until an error happens (for "live" MIDI data "over the wire"). io.EOF is the expected error that is returned when reading should stop.

Read does not close the src.

The messages are dispatched to the corresponding attached functions of the Reader.

They must be attached before Reader.Read is called and they must not be unset or replaced until Read returns. For more infomation about dealing with the MIDI messages, see Reader.

func (*Reader) ReadFrom added in v0.9.5

func (r *Reader) ReadFrom(in connect.In) error

ReadFrom configures the Reader to read from to the given MIDI in connection. The gomidi/connect package provides adapters to rtmidi and portaudio that fullfill the InConnection interface.

func (*Reader) ReadSMF

func (r *Reader) ReadSMF(src io.Reader, options ...smfreader.Option) error

ReadSMF reads midi messages from src (which is supposed to be the content of a standard midi file (SMF)) until an error or io.EOF happens.

ReadSMF does not close the src.

If the read content was a valid midi file, nil is returned.

The messages are dispatched to the corresponding attached functions of the Reader.

They must be attached before Reader.ReadSMF is called and they must not be unset or replaced until ReadSMF returns. For more infomation about dealing with the SMF midi messages, see Reader and SMFPosition.

func (*Reader) ReadSMFFile

func (r *Reader) ReadSMFFile(file string, options ...smfreader.Option) error

ReadSMFFile open, reads and closes a complete SMF file. If the read content was a valid midi file, nil is returned.

The messages are dispatched to the corresponding attached functions of the handler.

They must be attached before Reader.ReadSMF is called and they must not be unset or replaced until ReadSMF returns. For more infomation about dealing with the SMF midi messages, see Reader and SMFPosition.

func (*Reader) ReadSMFFileHeader added in v0.9.8

func (r *Reader) ReadSMFFileHeader(file string, options ...smfreader.Option) (smf.Header, error)

ReadSMFFileHeader reads just the header of a SMF file

func (*Reader) Resolution added in v0.9.12

func (r *Reader) Resolution() uint32

Resolution returns the ticks of a quarternote If it can't be determined, 0 is returned

func (*Reader) TempoBPM added in v0.17.0

func (r *Reader) TempoBPM() float64

BPM returns the current tempo in BPM (beats per minute)

func (*Reader) Ticks added in v0.9.2

func (r *Reader) Ticks(d time.Duration) uint32

Ticks returns the ticks that correspond to a duration while respecting the current tempo If it can't be determined, 0 is returned

func (*Reader) TimeAt

func (r *Reader) TimeAt(absTicks uint64) *time.Duration

TimeAt returns the time.Duration at the given absolute position counted from the beginning of the file, respecting all the tempo changes in between. If the time format is not of type smf.MetricTicks, nil is returned.

type ReaderOption

type ReaderOption func(*Reader)

ReaderOption configures the reader

func IgnoreMIDIClock added in v0.9.12

func IgnoreMIDIClock() ReaderOption

IgnoreMIDIClock lets the reader not use MIDI clock to calculate the tempo

func NoLogger

func NoLogger() ReaderOption

NoLogger is an option to disable the defaut logging of a Reader

func ReadingOptions

func ReadingOptions(options ...midireader.Option) ReaderOption

func SetLogger

func SetLogger(l Logger) ReaderOption

SetLogger allows to set a custom logger for the Reader

type SMFWriter

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

SMFWriter writes SMF MIDI data. Its methods must not be called concurrently

func NewSMF

func NewSMF(dest io.Writer, numtracks uint16, options ...smfwriter.Option) *SMFWriter

NewSMF returns a new SMFWriter that writes to dest. It panics if numtracks is == 0.

func (SMFWriter) Aftertouch added in v0.10.0

func (w SMFWriter) Aftertouch(pressure uint8) error

Aftertouch writes a channel pressure message for the current channel

func (SMFWriter) CcOff added in v0.10.0

func (w SMFWriter) CcOff(controller uint8) error

CcOff writes a control change message with a value of 0 (=off) for the current channel

func (SMFWriter) CcOn added in v0.10.0

func (w SMFWriter) CcOn(controller uint8) error

CcOn writes a control change message with a value of 127 (=on) for the current channel

func (SMFWriter) CoarseTuningRPN added in v0.13.0

func (w SMFWriter) CoarseTuningRPN(msbVal, lsbVal uint8) error

CoarseTuningRPN

func (SMFWriter) ConsolidateNotes added in v0.9.8

func (w SMFWriter) ConsolidateNotes(on bool)

ConsolidateNotes enables/disables the midi note consolidation (default: enabled) When enabled, midi note on/off messages are consolidated, that means the on/off state of every possible note on every channel is tracked and note on messages are only written, if the corresponding note is off and vice versa. Note on messages with a velocity of 0 behave the same way as note offs. The tracking of the notes is not cross SMF tracks, i.e. a meta.EndOfTrack message will reset the tracking. The consolidation should prevent "hanging" notes in most cases. If on is true, the note will be started tracking again (fresh state), assuming no note is currently running.

func (SMFWriter) ControlChange

func (w SMFWriter) ControlChange(controller, value uint8) error

ControlChange writes a control change message for the current channel For more comfortable use, used it in conjunction with the gomidi/cc package

func (*SMFWriter) Copyright

func (w *SMFWriter) Copyright(text string) error

Copyright writes the copyright meta message

func (*SMFWriter) Cuepoint

func (w *SMFWriter) Cuepoint(text string) error

Cuepoint writes the cuepoint meta message

func (*SMFWriter) DeprecatedChannel added in v0.10.0

func (w *SMFWriter) DeprecatedChannel(ch uint8) error

DeprecatedChannel writes the deprecated MIDI channel meta message

func (*SMFWriter) DeprecatedPort added in v0.10.0

func (w *SMFWriter) DeprecatedPort(port uint8) error

DeprecatedPort writes the deprecated MIDI port meta message

func (*SMFWriter) Device added in v0.10.0

func (w *SMFWriter) Device(port string) error

Device writes the device port meta message

func (*SMFWriter) EndOfTrack

func (w *SMFWriter) EndOfTrack() error

EndOfTrack signals the end of a track

func (SMFWriter) FineTuningRPN added in v0.13.0

func (w SMFWriter) FineTuningRPN(msbVal, lsbVal uint8) error

FineTuningRPN

func (*SMFWriter) Key

func (w *SMFWriter) Key(keysig meta.Key) error

Key writes the given key signature meta message. It is supposed to be used with the gomidi/midi/midimessage/meta/key package

func (*SMFWriter) KeySig added in v0.10.0

func (w *SMFWriter) KeySig(key uint8, ismajor bool, num uint8, isflat bool) error

KeySig writes the key signature meta message. A more comfortable way is to use the Key method in conjunction with the gomidi/midi/midimessage/meta/key package

func (*SMFWriter) Lyric

func (w *SMFWriter) Lyric(text string) error

Lyric writes the lyric meta message

func (*SMFWriter) Marker

func (w *SMFWriter) Marker(text string) error

Marker writes the marker meta message

func (*SMFWriter) Meter

func (w *SMFWriter) Meter(numerator, denominator uint8) error

Meter writes the time signature meta message in a more comfortable way. Numerator and Denominator are decimalw.

func (SMFWriter) MsbLsb

func (w SMFWriter) MsbLsb(msbControl, lsbControl uint8, value uint16) error

MsbLsb writes a Msb control change message, followed by a Lsb control change message for the current channel For more comfortable use, used it in conjunction with the gomidi/cc package

func (SMFWriter) NRPN added in v0.13.0

func (w SMFWriter) NRPN(val99, val98, msbVal, lsbVal uint8) error

NRPN message consisting of a val99 and val98 to identify the RPN and a msb and lsb for the value

func (SMFWriter) NRPNDecrement added in v0.13.0

func (w SMFWriter) NRPNDecrement(val99, val98 uint8) error

func (SMFWriter) NRPNIncrement added in v0.13.0

func (w SMFWriter) NRPNIncrement(val99, val98 uint8) error

func (SMFWriter) NoteOff

func (w SMFWriter) NoteOff(key uint8) error

NoteOff writes a note off message for the current channel By default, midi notes are consolidated (see ConsolidateNotes method)

func (SMFWriter) NoteOffVelocity added in v0.9.8

func (w SMFWriter) NoteOffVelocity(key, velocity uint8) error

NoteOffVelocity writes a note off message for the current channel with a velocity. By default, midi notes are consolidated (see ConsolidateNotes method)

func (SMFWriter) NoteOn

func (w SMFWriter) NoteOn(key, veloctiy uint8) error

NoteOn writes a note on message for the current channel By default, midi notes are consolidated (see ConsolidateNotes method)

func (SMFWriter) PitchBendSensitivityRPN added in v0.13.0

func (w SMFWriter) PitchBendSensitivityRPN(msbVal, lsbVal uint8) error

PitchBendSensitivityRPN sets the pitch bend range via RPN

func (SMFWriter) Pitchbend added in v0.10.0

func (w SMFWriter) Pitchbend(value int16) error

Pitchbend writes a pitch bend message for the current channel For reset value, use 0, for lowest -8191 and highest 8191 Or use the pitch constants of midimessage/channel

func (SMFWriter) PolyAftertouch added in v0.10.0

func (w SMFWriter) PolyAftertouch(key, pressure uint8) error

PolyAftertouch writes a key pressure message for the current channel

func (*SMFWriter) Program added in v0.10.0

func (w *SMFWriter) Program(text string) error

Program writes the program name meta message

func (SMFWriter) ProgramChange

func (w SMFWriter) ProgramChange(program uint8) error

ProgramChange writes a program change message for the current channel Program numbers start with 0 for program 1.

func (SMFWriter) RPN added in v0.13.0

func (w SMFWriter) RPN(val101, val100, msbVal, lsbVal uint8) error

RPN message consisting of a val101 and val100 to identify the RPN and a msb and lsb for the value

func (SMFWriter) RPNDecrement added in v0.13.0

func (w SMFWriter) RPNDecrement(val101, val100 uint8) error

func (SMFWriter) RPNIncrement added in v0.13.0

func (w SMFWriter) RPNIncrement(val101, val100 uint8) error

func (SMFWriter) ResetNRPN added in v0.13.0

func (w SMFWriter) ResetNRPN() error

ResetNRPN aka Null

func (SMFWriter) ResetRPN added in v0.13.0

func (w SMFWriter) ResetRPN() error

ResetRPN aka Null

func (*SMFWriter) SMPTE added in v0.10.0

func (w *SMFWriter) SMPTE(hour, minute, second, frame, fractionalFrame byte) error

SMPTE writes the SMPTE offset meta message

func (*SMFWriter) Sequence

func (w *SMFWriter) Sequence(text string) error

Sequence writes the sequence (name) meta message

func (*SMFWriter) SequenceNo added in v0.10.0

func (w *SMFWriter) SequenceNo(no uint16) error

SequenceNo writes the sequence number meta message

func (*SMFWriter) SequencerData added in v0.10.0

func (w *SMFWriter) SequencerData(data []byte) error

SequencerData writes a custom sequences specific meta message

func (SMFWriter) SetChannel

func (w SMFWriter) SetChannel(no uint8)

SetChannel sets the channel for the following midi messages Channel numbers are counted from 0 to 15 (MIDI channel 1 to 16). The initial channel number is 0.

func (*SMFWriter) SetDelta

func (w *SMFWriter) SetDelta(deltatime uint32)

SetDelta sets the delta ticks to the next message

func (SMFWriter) SysEx added in v0.10.0

func (w SMFWriter) SysEx(data []byte) error

SysEx writes system exclusive data

func (*SMFWriter) TempoBPM added in v0.17.0

func (w *SMFWriter) TempoBPM(bpm float64) error

Tempo writes the tempo meta message

func (*SMFWriter) Text

func (w *SMFWriter) Text(text string) error

Text writes the text meta message

func (*SMFWriter) TimeSig added in v0.10.0

func (w *SMFWriter) TimeSig(numerator, denominator, clocksPerClick, demiSemiQuaverPerQuarter uint8) error

TimeSig writes the time signature meta message. Numerator and Denominator are decimalw. If you don't want to deal with clocks per click and demisemiquaverperquarter, user the Meter method instead.

func (*SMFWriter) Track

func (w *SMFWriter) Track(track string) error

Track writes the track name aka instrument name meta message

func (SMFWriter) TuningBankSelectRPN added in v0.13.0

func (w SMFWriter) TuningBankSelectRPN(msbVal, lsbVal uint8) error

TuningBankSelectRPN

func (SMFWriter) TuningProgramSelectRPN added in v0.13.0

func (w SMFWriter) TuningProgramSelectRPN(msbVal, lsbVal uint8) error

TuningProgramSelectRPN

func (SMFWriter) Write added in v0.9.7

func (w SMFWriter) Write(msg midi.Message) error

Write writes the given midi.Message. By default, midi notes are consolidated (see ConsolidateNotes method)

type Writer

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

Writer writes live MIDI data. Its methods must not be called concurrently

func NewWriter

func NewWriter(dest io.Writer, options ...midiwriter.Option) *Writer

NewWriter creates and new Writer for writing of "live" MIDI data ("over the wire") By default it makes no use of the running status.

func WriteTo added in v0.9.5

func WriteTo(out connect.Out) *Writer

WriteTo returns a Writer that writes to the given MIDI out connection. The gomidi/connect package provides adapters to rtmidi and portaudio that fullfill the OutConnection interface.

func (*Writer) Activesense added in v0.10.0

func (w *Writer) Activesense() error

ActiveSensing writes the active sensing realtime message

func (Writer) Aftertouch added in v0.10.0

func (w Writer) Aftertouch(pressure uint8) error

Aftertouch writes a channel pressure message for the current channel

func (Writer) CcOff added in v0.10.0

func (w Writer) CcOff(controller uint8) error

CcOff writes a control change message with a value of 0 (=off) for the current channel

func (Writer) CcOn added in v0.10.0

func (w Writer) CcOn(controller uint8) error

CcOn writes a control change message with a value of 127 (=on) for the current channel

func (*Writer) Clock added in v0.17.0

func (w *Writer) Clock() error

Clock writes the timing clock realtime message

func (Writer) CoarseTuningRPN added in v0.13.0

func (w Writer) CoarseTuningRPN(msbVal, lsbVal uint8) error

CoarseTuningRPN

func (Writer) ConsolidateNotes added in v0.9.8

func (w Writer) ConsolidateNotes(on bool)

ConsolidateNotes enables/disables the midi note consolidation (default: enabled) When enabled, midi note on/off messages are consolidated, that means the on/off state of every possible note on every channel is tracked and note on messages are only written, if the corresponding note is off and vice versa. Note on messages with a velocity of 0 behave the same way as note offs. The tracking of the notes is not cross SMF tracks, i.e. a meta.EndOfTrack message will reset the tracking. The consolidation should prevent "hanging" notes in most cases. If on is true, the note will be started tracking again (fresh state), assuming no note is currently running.

func (*Writer) Continue

func (w *Writer) Continue() error

Continue writes the continue realtime message

func (Writer) ControlChange

func (w Writer) ControlChange(controller, value uint8) error

ControlChange writes a control change message for the current channel For more comfortable use, used it in conjunction with the gomidi/cc package

func (Writer) FineTuningRPN added in v0.13.0

func (w Writer) FineTuningRPN(msbVal, lsbVal uint8) error

FineTuningRPN

func (*Writer) MTC added in v0.10.0

func (w *Writer) MTC(code uint8) error

MTC writes the MIDI Timing Code system message

func (Writer) MsbLsb

func (w Writer) MsbLsb(msbControl, lsbControl uint8, value uint16) error

MsbLsb writes a Msb control change message, followed by a Lsb control change message for the current channel For more comfortable use, used it in conjunction with the gomidi/cc package

func (Writer) NRPN added in v0.13.0

func (w Writer) NRPN(val99, val98, msbVal, lsbVal uint8) error

NRPN message consisting of a val99 and val98 to identify the RPN and a msb and lsb for the value

func (Writer) NRPNDecrement added in v0.13.0

func (w Writer) NRPNDecrement(val99, val98 uint8) error

func (Writer) NRPNIncrement added in v0.13.0

func (w Writer) NRPNIncrement(val99, val98 uint8) error

func (Writer) NoteOff

func (w Writer) NoteOff(key uint8) error

NoteOff writes a note off message for the current channel By default, midi notes are consolidated (see ConsolidateNotes method)

func (Writer) NoteOffVelocity added in v0.9.8

func (w Writer) NoteOffVelocity(key, velocity uint8) error

NoteOffVelocity writes a note off message for the current channel with a velocity. By default, midi notes are consolidated (see ConsolidateNotes method)

func (Writer) NoteOn

func (w Writer) NoteOn(key, veloctiy uint8) error

NoteOn writes a note on message for the current channel By default, midi notes are consolidated (see ConsolidateNotes method)

func (Writer) PitchBendSensitivityRPN added in v0.13.0

func (w Writer) PitchBendSensitivityRPN(msbVal, lsbVal uint8) error

PitchBendSensitivityRPN sets the pitch bend range via RPN

func (Writer) Pitchbend added in v0.10.0

func (w Writer) Pitchbend(value int16) error

Pitchbend writes a pitch bend message for the current channel For reset value, use 0, for lowest -8191 and highest 8191 Or use the pitch constants of midimessage/channel

func (Writer) PolyAftertouch added in v0.10.0

func (w Writer) PolyAftertouch(key, pressure uint8) error

PolyAftertouch writes a key pressure message for the current channel

func (Writer) ProgramChange

func (w Writer) ProgramChange(program uint8) error

ProgramChange writes a program change message for the current channel Program numbers start with 0 for program 1.

func (Writer) RPN added in v0.13.0

func (w Writer) RPN(val101, val100, msbVal, lsbVal uint8) error

RPN message consisting of a val101 and val100 to identify the RPN and a msb and lsb for the value

func (Writer) RPNDecrement added in v0.13.0

func (w Writer) RPNDecrement(val101, val100 uint8) error

func (Writer) RPNIncrement added in v0.13.0

func (w Writer) RPNIncrement(val101, val100 uint8) error

func (*Writer) Reset

func (w *Writer) Reset() error

Reset writes the reset realtime message

func (Writer) ResetNRPN added in v0.13.0

func (w Writer) ResetNRPN() error

ResetNRPN aka Null

func (Writer) ResetRPN added in v0.13.0

func (w Writer) ResetRPN() error

ResetRPN aka Null

func (*Writer) SPP added in v0.10.0

func (w *Writer) SPP(ptr uint16) error

SPP writes the song position pointer system message

func (Writer) SetChannel

func (w Writer) SetChannel(no uint8)

SetChannel sets the channel for the following midi messages Channel numbers are counted from 0 to 15 (MIDI channel 1 to 16). The initial channel number is 0.

func (*Writer) SongSelect

func (w *Writer) SongSelect(song uint8) error

SongSelect writes the song select system message

func (*Writer) Start

func (w *Writer) Start() error

Start writes the start realtime message

func (*Writer) Stop

func (w *Writer) Stop() error

Stop writes the stop realtime message

func (Writer) SysEx added in v0.10.0

func (w Writer) SysEx(data []byte) error

SysEx writes system exclusive data

func (*Writer) Tick

func (w *Writer) Tick() error

Tick writes the tick realtime message

func (*Writer) Tune added in v0.10.0

func (w *Writer) Tune() error

Tune writes the tune request system message

func (Writer) TuningBankSelectRPN added in v0.13.0

func (w Writer) TuningBankSelectRPN(msbVal, lsbVal uint8) error

TuningBankSelectRPN

func (Writer) TuningProgramSelectRPN added in v0.13.0

func (w Writer) TuningProgramSelectRPN(msbVal, lsbVal uint8) error

TuningProgramSelectRPN

func (Writer) Write added in v0.9.7

func (w Writer) Write(msg midi.Message) error

Write writes the given midi.Message. By default, midi notes are consolidated (see ConsolidateNotes method)

Directories

Path Synopsis
examples
imported
rtmidi Module

Jump to

Keyboard shortcuts

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