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" "gitlab.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.Meter(4, 4) /* set the meter of 4/4 */ wr.SetChannel(2 /* valid: 0-15 */) wr.NoteOn(65 /* key */, 90 /* velocity */) wr.Forward(1, 0, 0) // forwards the cursor to the next bar (we make a whole note) 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 ¶
- Constants
- Variables
- func NewSMFFile(file string, numtracks uint16, writer func(*SMFWriter) error, ...) error
- type Driver
- type In
- type Logger
- type Out
- type Port
- type Position
- type Reader
- func (r *Reader) Duration(deltaticks uint32) time.Duration
- func (r *Reader) Read(src io.Reader) (err error)
- func (r *Reader) ReadFrom(in In) error
- func (r *Reader) ReadSMF(src io.Reader, options ...smfreader.Option) error
- func (r *Reader) ReadSMFFile(file string, options ...smfreader.Option) error
- func (r *Reader) ReadSMFFileHeader(file string, options ...smfreader.Option) (smf.Header, error)
- func (r *Reader) Resolution() uint32
- func (r *Reader) TempoBPM() float64
- func (r *Reader) Ticks(d time.Duration) uint32
- func (r *Reader) TimeAt(absTicks uint64) *time.Duration
- type ReaderOption
- type SMFWriter
- func (w SMFWriter) Aftertouch(pressure uint8) error
- func (w SMFWriter) CcOff(controller uint8) error
- func (w SMFWriter) CcOn(controller uint8) error
- func (w SMFWriter) CoarseTuningRPN(msbVal, lsbVal uint8) error
- func (w SMFWriter) ConsolidateNotes(on bool)
- func (w SMFWriter) ControlChange(controller, value uint8) error
- func (w *SMFWriter) Copyright(text string) error
- func (w *SMFWriter) Cuepoint(text string) error
- func (w *SMFWriter) DeprecatedChannel(ch uint8) error
- func (w *SMFWriter) DeprecatedPort(port uint8) error
- func (w *SMFWriter) Device(port string) error
- func (w *SMFWriter) EndOfTrack() error
- func (w SMFWriter) FineTuningRPN(msbVal, lsbVal uint8) error
- func (w *SMFWriter) Forward(nbars, num, denom uint32)
- func (w SMFWriter) GMReset(prog uint8) error
- func (w *SMFWriter) Key(keysig meta.Key) error
- func (w *SMFWriter) KeySig(key uint8, ismajor bool, num uint8, isflat bool) error
- func (w *SMFWriter) Lyric(text string) error
- func (w *SMFWriter) Marker(text string) error
- func (w *SMFWriter) Meter(numerator, denominator uint8) error
- func (w SMFWriter) MsbLsb(msbControl, lsbControl uint8, value uint16) error
- func (w SMFWriter) NRPN(val99, val98, msbVal, lsbVal uint8) error
- func (w SMFWriter) NRPNDecrement(val99, val98 uint8) error
- func (w SMFWriter) NRPNIncrement(val99, val98 uint8) error
- func (w SMFWriter) NoteOff(key uint8) error
- func (w SMFWriter) NoteOffVelocity(key, velocity uint8) error
- func (w SMFWriter) NoteOn(key, veloctiy uint8) error
- func (w SMFWriter) PitchBendSensitivityRPN(msbVal, lsbVal uint8) error
- func (w SMFWriter) Pitchbend(value int16) error
- func (w SMFWriter) PolyAftertouch(key, pressure uint8) error
- func (w *SMFWriter) Program(text string) error
- func (w SMFWriter) ProgramChange(program uint8) error
- func (w SMFWriter) RPN(val101, val100, msbVal, lsbVal uint8) error
- func (w SMFWriter) RPNDecrement(val101, val100 uint8) error
- func (w SMFWriter) RPNIncrement(val101, val100 uint8) error
- func (w SMFWriter) Reset(bank uint8, prog uint8) error
- func (w SMFWriter) ResetNRPN() error
- func (w SMFWriter) ResetRPN() error
- func (w *SMFWriter) SMPTE(hour, minute, second, frame, fractionalFrame byte) error
- func (w *SMFWriter) Sequence(text string) error
- func (w *SMFWriter) SequenceNo(no uint16) error
- func (w *SMFWriter) SequencerData(data []byte) error
- func (w SMFWriter) SetChannel(no uint8)
- func (w *SMFWriter) SetDelta(deltatime uint32)
- func (w SMFWriter) Silence(ch int8, force bool) (err error)
- func (w SMFWriter) SysEx(data []byte) error
- func (w *SMFWriter) TempoBPM(bpm float64) error
- func (w *SMFWriter) Text(text string) error
- func (w *SMFWriter) TimeSig(numerator, denominator, clocksPerClick, demiSemiQuaverPerQuarter uint8) error
- func (w *SMFWriter) Track(track string) error
- func (w SMFWriter) TuningBankSelectRPN(msbVal, lsbVal uint8) error
- func (w SMFWriter) TuningProgramSelectRPN(msbVal, lsbVal uint8) error
- func (w SMFWriter) Write(msg midi.Message) error
- type Writer
- func (w *Writer) Activesense() error
- func (w Writer) Aftertouch(pressure uint8) error
- func (w Writer) CcOff(controller uint8) error
- func (w Writer) CcOn(controller uint8) error
- func (w *Writer) Clock() error
- func (w Writer) CoarseTuningRPN(msbVal, lsbVal uint8) error
- func (w Writer) ConsolidateNotes(on bool)
- func (w *Writer) Continue() error
- func (w Writer) ControlChange(controller, value uint8) error
- func (w Writer) FineTuningRPN(msbVal, lsbVal uint8) error
- func (w Writer) GMReset(prog uint8) error
- func (w *Writer) MTC(code uint8) error
- func (w Writer) MsbLsb(msbControl, lsbControl uint8, value uint16) error
- func (w Writer) NRPN(val99, val98, msbVal, lsbVal uint8) error
- func (w Writer) NRPNDecrement(val99, val98 uint8) error
- func (w Writer) NRPNIncrement(val99, val98 uint8) error
- func (w Writer) NoteOff(key uint8) error
- func (w Writer) NoteOffVelocity(key, velocity uint8) error
- func (w Writer) NoteOn(key, veloctiy uint8) error
- func (w Writer) PitchBendSensitivityRPN(msbVal, lsbVal uint8) error
- func (w Writer) Pitchbend(value int16) error
- func (w Writer) PolyAftertouch(key, pressure uint8) error
- func (w Writer) ProgramChange(program uint8) error
- func (w Writer) RPN(val101, val100, msbVal, lsbVal uint8) error
- func (w Writer) RPNDecrement(val101, val100 uint8) error
- func (w Writer) RPNIncrement(val101, val100 uint8) error
- func (w *Writer) Reset() error
- func (w Writer) ResetNRPN() error
- func (w Writer) ResetRPN() error
- func (w *Writer) SPP(ptr uint16) error
- func (w Writer) SetChannel(no uint8)
- func (w Writer) Silence(ch int8, force bool) (err error)
- func (w *Writer) SongSelect(song uint8) error
- func (w *Writer) Start() error
- func (w *Writer) Stop() error
- func (w Writer) SysEx(data []byte) error
- func (w *Writer) Tick() error
- func (w *Writer) Tune() error
- func (w Writer) TuningBankSelectRPN(msbVal, lsbVal uint8) error
- func (w Writer) TuningProgramSelectRPN(msbVal, lsbVal uint8) error
- func (w Writer) Write(msg midi.Message) error
Examples ¶
Constants ¶
const LiveResolution = smf.MetricTicks(1920)
LiveResolution is the resolution used for live over the wire reading with Reader.ReadFrom
Variables ¶
var ErrClosed = fmt.Errorf("ERROR: port is closed")
ErrClosed should be returned from a driver when trying to write to a closed port.
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 Driver ¶ added in v1.7.4
type Driver interface { // Ins returns the available MIDI input ports Ins() ([]In, error) // Outs returns the available MIDI output ports Outs() ([]Out, error) // String returns the name of the driver String() string // Close closes the driver. Must be called for cleanup at the end of a session Close() error }
Driver is a driver for MIDI connections.
type In ¶ added in v1.7.4
type In interface { Port // SetListener sets the callback function that is called when data arrives // println(big.NewRat(math.MaxInt64,1000 /* milliseonds */ *1000 /* seconds */ *60 /* minutes */ *60 /* hours */ *24 /* days */ *365 /* years */).FloatString(0)) // output: 292471 // => a ascending timestamp based on microseconds would wrap after 292471 years SetListener(func(data []byte, deltaMicroseconds int64)) error // StopListening stops the listening // When closing an MIDI input port, StopListening must be called before (from the driver) StopListening() error }
In is an interface for a MIDI in port
type Logger ¶
type Logger interface {
Printf(format string, vals ...interface{})
}
Logger is the inferface used by Reader for logging incoming messages.
type Out ¶ added in v1.7.4
type Out interface { Port // Send sends the given MIDI bytes over the wire. // If the port is closed, ErrClosed must be returned Send([]byte) error }
Out is an interface for a MIDI out port
type Port ¶ added in v1.7.4
type Port interface { // Open opens the MIDI port. An implementation should save the open state to make it // save to call open when the port is already open without getting an error. Open() error // Close closes the MIDI port. An implementation should save the open state to make it // save to call close when the port is already closed without getting an error. Close() error // IsOpen returns wether the MIDI port is open IsOpen() bool // Number returns the number of the MIDI port. It is only guaranteed that the numbers are unique within // MIDI port groups i.e. within MIDI input ports and MIDI output ports. So there may be the same number // for a given MIDI input port and some MIDI output port. Or not - that depends on the underlying driver. // outport Number() int // String represents the MIDI port by a string, aka name. String() string // Underlying returns the underlying driver to allow further adjustments // When using the underlying driver, the use user must take care of proper opening/closing etc. Underlying() interface{} }
Port is an interface for a MIDI port
type Position ¶ added in v1.7.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 ¶ added in v1.7.0
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 ¶ added in v1.7.0
func NewReader(opts ...ReaderOption) *Reader
NewReader returns a new Reader
func (*Reader) Duration ¶ added in v1.7.0
Duration returns the duration for the given delta ticks, respecting the current tempo
func (*Reader) Read ¶ added in v1.7.0
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 v1.7.0
ReadFrom configures the Reader to read from to the given MIDI in connection.
func (*Reader) ReadSMF ¶ added in v1.7.0
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 ¶ added in v1.7.0
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 v1.7.0
ReadSMFFileHeader reads just the header of a SMF file
func (*Reader) Resolution ¶ added in v1.7.0
Resolution returns the ticks of a quarternote If it can't be determined, 0 is returned
func (*Reader) Ticks ¶ added in v1.7.0
Ticks returns the ticks that correspond to a duration while respecting the current tempo If it can't be determined, 0 is returned
type ReaderOption ¶ added in v1.7.0
type ReaderOption func(*Reader)
ReaderOption configures the reader
func IgnoreMIDIClock ¶ added in v1.7.0
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 ¶ added in v1.7.0
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 { smf.MetricTicks // contains filtered or unexported fields }
SMFWriter writes SMF MIDI data. Its methods must not be called concurrently
func NewSMF ¶ added in v1.7.0
NewSMF returns a new SMFWriter that writes to dest. It panics if numtracks is == 0.
func (SMFWriter) Aftertouch ¶ added in v1.7.0
Aftertouch writes a channel pressure message for the current channel
func (SMFWriter) CcOff ¶ added in v1.7.0
CcOff writes a control change message with a value of 0 (=off) for the current channel
func (SMFWriter) CcOn ¶ added in v1.7.0
CcOn writes a control change message with a value of 127 (=on) for the current channel
func (SMFWriter) CoarseTuningRPN ¶ added in v1.7.0
CoarseTuningRPN
func (SMFWriter) ConsolidateNotes ¶ added in v1.7.0
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 ¶
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) DeprecatedChannel ¶ added in v1.7.0
DeprecatedChannel writes the deprecated MIDI channel meta message
func (*SMFWriter) DeprecatedPort ¶ added in v1.7.0
DeprecatedPort writes the deprecated MIDI port meta message
func (*SMFWriter) EndOfTrack ¶
EndOfTrack signals the end of a track
func (SMFWriter) FineTuningRPN ¶ added in v1.7.0
FineTuningRPN
func (*SMFWriter) Forward ¶ added in v1.8.0
Forward sets the cursor based on the given number of bars and ratio of whole notes. The cursor is the current position where the next event will be inserted. In the background it sets the delta to the next event. The cursor can only move forward.
Examples:
To move the cursor to the 2nd next bar (respecting time signature changes), use
Forward(2,0,0)
To move the cursor by 23 8ths (independent from time signatures), use
Forward(0,23,8)
To move the cursor to the 3rd 4th of the next bar (respecting time signature changes), use
Forward(1,3,4)
Important notes:
- Always put time signature changes at the beginning of a bar.
- Never forward more than once without setting a event in between.
func (SMFWriter) GMReset ¶ added in v1.7.0
GMReset resets the channel to some GM based standards (see Reset) and sets the given GM program.
func (*SMFWriter) Key ¶
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 v1.7.0
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) Meter ¶
Meter writes the time signature meta message in a more comfortable way. Numerator and Denominator are decimalw.
func (SMFWriter) MsbLsb ¶ added in v1.7.0
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 v1.7.0
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 v1.7.0
func (SMFWriter) NRPNIncrement ¶ added in v1.7.0
func (SMFWriter) NoteOff ¶
NoteOff writes a note off message for the current channel By default, midi notes are consolidated (see ConsolidateNotes method)
func (SMFWriter) NoteOffVelocity ¶ added in v1.7.0
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 ¶
NoteOn writes a note on message for the current channel By default, midi notes are consolidated (see ConsolidateNotes method)
func (SMFWriter) PitchBendSensitivityRPN ¶ added in v1.7.0
PitchBendSensitivityRPN sets the pitch bend range via RPN
func (SMFWriter) Pitchbend ¶ added in v1.7.0
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 v1.7.0
PolyAftertouch writes a key pressure message for the current channel
func (SMFWriter) ProgramChange ¶
ProgramChange writes a program change message for the current channel Program numbers start with 0 for program 1.
func (SMFWriter) RPN ¶ added in v1.7.0
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 v1.7.0
func (SMFWriter) RPNIncrement ¶ added in v1.7.0
func (SMFWriter) Reset ¶ added in v1.7.0
Reset "resets" channel to some established defaults
bank select -> bank program change -> prog cc all controllers off cc volume -> 100 cc expression -> 127 cc hold pedal -> off cc pan position -> 64 cc RPN pitch bend sensitivity -> 2 (semitones)
func (SMFWriter) ResetNRPN ¶ added in v1.7.0
func (w SMFWriter) ResetNRPN() error
ResetNRPN aka Null
func (*SMFWriter) SequenceNo ¶ added in v1.7.0
SequenceNo writes the sequence number meta message
func (*SMFWriter) SequencerData ¶ added in v1.7.0
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 ¶
SetDelta sets the delta ticks to the next message It should mostly not be needed, use Forward instead to advance in musical time.
func (SMFWriter) Silence ¶ added in v1.7.0
Silence sends a note off message for every running note on the given channel. If the channel is -1, every channel is affected. If note consolidation is switched off, notes aren't tracked and therefor every possible note will get a note off. This could also be enforced by setting force to true. If force is true, additionally the cc messages AllNotesOff (123) and AllSoundOff (120) are send. If channel is > 15, the method panics. The error or not error of the last write is returned. (i.e. it does not return on the first error, but tries everything instead to make it silent)
func (*SMFWriter) TimeSig ¶ added in v1.7.0
func (w *SMFWriter) TimeSig(numerator, denominator, clocksPerClick, demiSemiQuaverPerQuarter uint8) error
TimeSig writes the time signature meta message. Numerator and Denominator are decimal. If you don't want to deal with clocks per click and demisemiquaverperquarter, user the Meter method instead.
func (SMFWriter) TuningBankSelectRPN ¶ added in v1.7.0
TuningBankSelectRPN
func (SMFWriter) TuningProgramSelectRPN ¶ added in v1.7.0
TuningProgramSelectRPN
type Writer ¶ added in v1.7.0
type Writer struct {
// contains filtered or unexported fields
}
Writer writes live MIDI data. Its methods must not be called concurrently
func NewWriter ¶ added in v1.7.0
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 v1.7.0
WriteTo returns a Writer that writes to the given MIDI out connection.
func (*Writer) Activesense ¶ added in v1.7.0
ActiveSensing writes the active sensing realtime message
func (Writer) Aftertouch ¶ added in v1.7.0
Aftertouch writes a channel pressure message for the current channel
func (Writer) CcOff ¶ added in v1.7.0
CcOff writes a control change message with a value of 0 (=off) for the current channel
func (Writer) CcOn ¶ added in v1.7.0
CcOn writes a control change message with a value of 127 (=on) for the current channel
func (Writer) CoarseTuningRPN ¶ added in v1.7.0
CoarseTuningRPN
func (Writer) ConsolidateNotes ¶ added in v1.7.0
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) ControlChange ¶ added in v1.7.0
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 v1.7.0
FineTuningRPN
func (Writer) GMReset ¶ added in v1.7.0
GMReset resets the channel to some GM based standards (see Reset) and sets the given GM program.
func (Writer) MsbLsb ¶ added in v1.7.0
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 v1.7.0
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 v1.7.0
func (Writer) NRPNIncrement ¶ added in v1.7.0
func (Writer) NoteOff ¶ added in v1.7.0
NoteOff writes a note off message for the current channel By default, midi notes are consolidated (see ConsolidateNotes method)
func (Writer) NoteOffVelocity ¶ added in v1.7.0
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 ¶ added in v1.7.0
NoteOn writes a note on message for the current channel By default, midi notes are consolidated (see ConsolidateNotes method)
func (Writer) PitchBendSensitivityRPN ¶ added in v1.7.0
PitchBendSensitivityRPN sets the pitch bend range via RPN
func (Writer) Pitchbend ¶ added in v1.7.0
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 v1.7.0
PolyAftertouch writes a key pressure message for the current channel
func (Writer) ProgramChange ¶ added in v1.7.0
ProgramChange writes a program change message for the current channel Program numbers start with 0 for program 1.
func (Writer) RPN ¶ added in v1.7.0
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 v1.7.0
func (Writer) RPNIncrement ¶ added in v1.7.0
func (Writer) SetChannel ¶ added in v1.7.0
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) Silence ¶ added in v1.7.0
Silence sends a note off message for every running note on the given channel. If the channel is -1, every channel is affected. If note consolidation is switched off, notes aren't tracked and therefor every possible note will get a note off. This could also be enforced by setting force to true. If force is true, additionally the cc messages AllNotesOff (123) and AllSoundOff (120) are send. If channel is > 15, the method panics. The error or not error of the last write is returned. (i.e. it does not return on the first error, but tries everything instead to make it silent)
func (*Writer) SongSelect ¶ added in v1.7.0
SongSelect writes the song select system message
func (Writer) TuningBankSelectRPN ¶ added in v1.7.0
TuningBankSelectRPN
func (Writer) TuningProgramSelectRPN ¶ added in v1.7.0
TuningProgramSelectRPN