Documentation
¶
Overview ¶
Package smf helps with reading and writing of Standard MIDI Files.
The most common time resolution for SMF files are metric ticks. They define, how many ticks a quarter note is divided into.
A SMF has of one or more tracks. A track is a slice of events and each event has a delta in ticks to the previous event and a message.
The smf package has its own Message type that forms the events and tracks. However it is fully transparent to the midi.Message type and both types are used in tandem when adding messages to a track with the Add method.
A created track must be closed with its Close method. The track can then be added to the SMF, which then can be written to an io.Writer or a file.
When reading, the tracks contain the resulting messages. The methods of the Message type can then be used to get the different informations from the message.
There are also helper functions for playing and recording.
The TracksReader provides handy shortcuts for reading multiple tracks and also converts the time, based on the tick resolution and the tempo changes.
Example ¶
// we write a SMF file into a buffer and read it back var ( bf bytes.Buffer clock = smf.MetricTicks(96) // resolution: 96 ticks per quarternote 960 is also a common choice general, piano, bass smf.Track // our tracks ) // first track must have tempo and meter informations general.Add(0, smf.MetaTrackSequenceName("general")) general.Add(0, smf.MetaMeter(3, 4)) general.Add(0, smf.MetaTempo(140)) general.Add(clock.Ticks4th()*6, smf.MetaTempo(130)) general.Add(clock.Ticks4th(), smf.MetaTempo(135)) general.Close(0) // don't forget to close a track piano.Add(0, smf.MetaInstrument("Piano")) piano.Add(0, midi.ProgramChange(0, gm.Instr_HonkytonkPiano.Value())) piano.Add(0, midi.NoteOn(0, 76, 120)) // duration: a quarter note (96 ticks in our case) piano.Add(clock.Ticks4th(), midi.NoteOff(0, 76)) piano.Close(0) bass.Add(0, smf.MetaInstrument("Bass")) bass.Add(0, midi.ProgramChange(1, gm.Instr_AcousticBass.Value())) bass.Add(clock.Ticks4th(), midi.NoteOn(1, 47, 64)) bass.Add(clock.Ticks4th()*3, midi.NoteOff(1, 47)) bass.Close(0) // create the SMF and add the tracks s := smf.New() s.TimeFormat = clock s.Add(general) s.Add(piano) s.Add(bass) // write the bytes to the buffer _, err := s.WriteTo(&bf) if err != nil { fmt.Printf("ERROR: %s", err.Error()) return } // read the bytes s, err = smf.ReadFrom(bytes.NewReader(bf.Bytes())) if err != nil { fmt.Printf("ERROR: %s", err.Error()) return } fmt.Printf("got %v tracks\n", len(s.Tracks)) for no, track := range s.Tracks { // it might be a good idea to go from delta ticks to absolute ticks. var absTicks uint64 var trackname string var channel, program uint8 var gm_name string for _, ev := range track { absTicks += uint64(ev.Delta) msg := ev.Message if msg.Type() == smf.MetaEndOfTrackMsg { // ignore continue } switch { case msg.GetMetaTrackName(&trackname): // set the trackname case msg.GetMetaInstrument(&trackname): // set the trackname based on instrument name case msg.GetProgramChange(&channel, &program): gm_name = "(" + gm.Instr(program).String() + ")" default: fmt.Printf("track %v %s %s @%v %s\n", no, trackname, gm_name, absTicks, ev.Message) } } }
Output: got 3 tracks track 0 general @0 MetaTimeSig meter: 3/4 track 0 general @0 MetaTempo bpm: 140.00 track 0 general @576 MetaTempo bpm: 130.00 track 0 general @672 MetaTempo bpm: 135.00 track 1 Piano (HonkytonkPiano) @0 NoteOn channel: 0 key: 76 velocity: 120 track 1 Piano (HonkytonkPiano) @96 NoteOff channel: 0 key: 76 track 2 Bass (AcousticBass) @96 NoteOn channel: 1 key: 47 velocity: 64 track 2 Bass (AcousticBass) @384 NoteOff channel: 1 key: 47
Index ¶
- Constants
- Variables
- func RecordTo(inport drivers.In, bpm float64, filename string) (stop func() error, err error)
- type Event
- type Key
- type Logger
- type Message
- func AMaj() Message
- func AMin() Message
- func AbMaj() Message
- func BMaj() Message
- func BMin() Message
- func BbMaj() Message
- func BbMin() Message
- func CMaj() Message
- func CMin() Message
- func CsharpMin() Message
- func DMaj() Message
- func DMin() Message
- func DbMaj() Message
- func DsharpMin() Message
- func EMaj() Message
- func EMin() Message
- func EbMaj() Message
- func EbMin() Message
- func FMaj() Message
- func FMin() Message
- func FsharpMaj() Message
- func FsharpMin() Message
- func GMaj() Message
- func GMin() Message
- func GbMaj() Message
- func GsharpMin() Message
- func MetaChannel(ch uint8) Message
- func MetaCopyright(text string) Message
- func MetaCuepoint(text string) Message
- func MetaDevice(text string) Message
- func MetaInstrument(text string) Message
- func MetaKey(key uint8, isMajor bool, num uint8, isFlat bool) Message
- func MetaLyric(text string) Message
- func MetaMarker(text string) Message
- func MetaMeter(num, denom uint8) Message
- func MetaPort(p uint8) Message
- func MetaProgram(text string) Message
- func MetaSMPTE(hour, minute, second, frame, fractionalFrame byte) Message
- func MetaSequenceNo(no uint16) Message
- func MetaSequencerData(data []byte) Message
- func MetaTempo(bpm float64) Message
- func MetaText(text string) Message
- func MetaTimeSig(numerator, denominator, clocksPerClick, demiSemiQuaverPerQuarter uint8) Message
- func MetaTrackSequenceName(text string) Message
- func (m Message) Bytes() []byte
- func (m Message) GetAfterTouch(channel, pressure *uint8) (is bool)
- func (m Message) GetChannel(channel *uint8) (is bool)
- func (m Message) GetControlChange(channel, controller, value *uint8) (is bool)
- func (m Message) GetMetaChannel(channel *uint8) bool
- func (m Message) GetMetaCopyright(text *string) (is bool)
- func (m Message) GetMetaCuepoint(text *string) (is bool)
- func (m Message) GetMetaDevice(text *string) (is bool)
- func (m Message) GetMetaInstrument(text *string) (is bool)
- func (m Message) GetMetaKey(key *Key) bool
- func (m Message) GetMetaKeySig(key, num *uint8, isMajor *bool, isFlat *bool) bool
- func (m Message) GetMetaLyric(text *string) (is bool)
- func (m Message) GetMetaMarker(text *string) (is bool)
- func (m Message) GetMetaMeter(num, denom *uint8) (is bool)
- func (m Message) GetMetaPort(port *uint8) bool
- func (m Message) GetMetaProgramName(text *string) (is bool)
- func (m Message) GetMetaSMPTEOffsetMsg(hour, minute, second, frame, fractframe *uint8) bool
- func (m Message) GetMetaSeqData(bt *[]byte) bool
- func (m Message) GetMetaSeqNumber(sequenceNumber *uint16) bool
- func (m Message) GetMetaTempo(bpm *float64) (is bool)
- func (m Message) GetMetaText(text *string) (is bool)
- func (m Message) GetMetaTimeSig(numerator, denominator, clocksPerClick, demiSemiQuaverPerQuarter *uint8) (is bool)
- func (m Message) GetMetaTrackName(text *string) (is bool)
- func (m Message) GetNoteEnd(channel, key *uint8) (is bool)
- func (m Message) GetNoteOff(channel, key, velocity *uint8) (is bool)
- func (m Message) GetNoteOn(channel, key, velocity *uint8) (is bool)
- func (m Message) GetNoteStart(channel, key, velocity *uint8) (is bool)
- func (m Message) GetPitchBend(channel *uint8, relative *int16, absolute *uint16) (is bool)
- func (m Message) GetPolyAfterTouch(channel, key, pressure *uint8) (is bool)
- func (m Message) GetProgramChange(channel, program *uint8) (is bool)
- func (m Message) GetSysEx(bt *[]byte) bool
- func (m Message) Is(t midi.Type) bool
- func (m Message) IsMeta() bool
- func (m Message) IsOneOf(checkers ...midi.Type) bool
- func (m Message) IsPlayable() bool
- func (m Message) String() string
- func (m Message) Type() midi.Type
- type MetricTicks
- func (q MetricTicks) Duration(fractionalBPM float64, deltaTicks uint32) time.Duration
- func (q MetricTicks) In64ths(deltaTicks uint32) uint32
- func (q MetricTicks) Resolution() uint16
- func (q MetricTicks) String() string
- func (q MetricTicks) Ticks(fractionalBPM float64, d time.Duration) (ticks uint32)
- func (q MetricTicks) Ticks1024th() uint32
- func (q MetricTicks) Ticks128th() uint32
- func (q MetricTicks) Ticks16th() uint32
- func (q MetricTicks) Ticks256th() uint32
- func (q MetricTicks) Ticks32th() uint32
- func (q MetricTicks) Ticks4th() uint32
- func (q MetricTicks) Ticks512th() uint32
- func (q MetricTicks) Ticks64th() uint32
- func (q MetricTicks) Ticks8th() uint32
- type ReadOption
- type SMF
- func (s *SMF) Add(t Track) error
- func (src SMF) ConvertToSMF1() (dest SMF)
- func (s SMF) Format() uint16
- func (s *SMF) NumTracks() uint16
- func (s *SMF) RecordFrom(inport drivers.In, bpm float64) (stop func(), err error)
- func (s SMF) String() string
- func (s *SMF) TempoChanges() TempoChanges
- func (s *SMF) TimeAt(absTicks int64) (absTimeMicroSec int64)
- func (s *SMF) WriteFile(file string) error
- func (s *SMF) WriteTo(f io.Writer) (size int64, err error)
- type TempoChange
- type TempoChanges
- type TimeCode
- type TimeFormat
- type Track
- func (t *Track) Add(deltaticks uint32, msgs ...[]byte)
- func (t *Track) Close(deltaticks uint32)
- func (t Track) IsClosed() bool
- func (t Track) IsEmpty() bool
- func (t *Track) RecordFrom(inPort drivers.In, ticks MetricTicks, bpm float64) (stop func(), err error)
- func (t *Track) SendTo(resolution MetricTicks, tc TempoChanges, ...)
- type TrackEvent
- type TrackEvents
- type TracksReader
- func (t *TracksReader) Do(fn func(TrackEvent)) *TracksReader
- func (t *TracksReader) Error() error
- func (t *TracksReader) MultiPlay(trackouts map[int]drivers.Out) error
- func (t *TracksReader) Only(mtypes ...midi.Type) *TracksReader
- func (t *TracksReader) Play(out drivers.Out) error
- func (t *TracksReader) SMF() *SMF
Examples ¶
Constants ¶
const ( // MetaChannelMsg is a MIDI channel meta message MetaChannelMsg midi.Type = 70 + iota // MetaCopyrightMsg is a MIDI copyright meta message MetaCopyrightMsg // MetaCuepointMsg is a MIDI cuepoint meta message MetaCuepointMsg // MetaDeviceMsg is a MIDI device meta message MetaDeviceMsg // MetaEndOfTrackMsg is a MIDI end of track meta message MetaEndOfTrackMsg // MetaInstrumentMsg is a MIDI instrument meta message MetaInstrumentMsg // MetaKeySigMsg is a MIDI key signature meta message MetaKeySigMsg // MetaLyricMsg is a MIDI lyrics meta message MetaLyricMsg // MetaTextMsg is a MIDI text meta message MetaTextMsg // MetaMarkerMsg is a MIDI marker meta message MetaMarkerMsg // MetaPortMsg is a MIDI port meta message MetaPortMsg // MetaSeqNumberMsg is a MIDI sequencer number meta message MetaSeqNumberMsg // MetaSeqDataMsg is a MIDI sequencer data meta message MetaSeqDataMsg // MetaTempoMsg is a MIDI tempo meta message MetaTempoMsg // MetaTimeSigMsg is a MIDI time signature meta message MetaTimeSigMsg // MetaTrackNameMsg is a MIDI track name meta message MetaTrackNameMsg // MetaSMPTEOffsetMsg is a MIDI smpte offset meta message MetaSMPTEOffsetMsg // MetaUndefinedMsg is an undefined MIDI meta message MetaUndefinedMsg // MetaProgramNameMsg is a MIDI program name meta message MetaProgramNameMsg )
const (
MetaMsg midi.Type = -5
)
Variables ¶
var ( // ErrMissing is the error returned, if there is no more data, but tracks are missing ErrMissing = errors.New("incomplete, tracks missing") // ErrFinished is returned ErrFinished = errors.New("reading of SMF finished successfully") )
var EOT = _MetaMessage(byteEndOfTrack, nil)
EOT is an End Of Track meta message. Don't use it directly.
Functions ¶
Types ¶
type Message ¶
type Message []byte
Message is a MIDI message that might appear in a SMF file, i.e. channel messages, sysex messages and meta messages.
func CsharpMin ¶
func CsharpMin() Message
CsharpMin returns the MIDI key signature meta message for C# Minor
func DsharpMin ¶
func DsharpMin() Message
DsharpMin returns the MIDI key signature meta message for D# Minor
func FsharpMaj ¶
func FsharpMaj() Message
FsharpMaj returns the MIDI key signature meta message for F# Major
func FsharpMin ¶
func FsharpMin() Message
FsharpMin returns the MIDI key signature meta message for F# Minor
func GsharpMin ¶
func GsharpMin() Message
GsharpMin returns the MIDI key signature meta message for G# Minor
func MetaCopyright ¶
MetaCopyright returns a copyright meta message
func MetaCuepoint ¶
MetaCuepoint returns a cuepoint meta message
func MetaInstrument ¶
MetaInstrument returns an instrument meta message
func MetaSequenceNo ¶
MetaSequenceNo returns a sequence number meta message
func MetaSequencerData ¶
MetaSequencerData returns a sequencer data meta message
func MetaTimeSig ¶
MetaTimeSig returns a time signature meta message.
func MetaTrackSequenceName ¶
MetaTrackSequenceName returns a track sequence name meta message.
func (Message) GetAfterTouch ¶
GetAfterTouch returns true if (and only if) the message is a AfterTouchMsg. Then it also extracts the data to the given arguments
func (Message) GetChannel ¶
GetChannel returns true if (and only if) the message is a ChannelMsg. Then it also extracts the data to the given arguments
func (Message) GetControlChange ¶
GetControlChange returns true if (and only if) the message is a ControlChangeMsg. Then it also extracts the data to the given arguments
func (Message) GetMetaChannel ¶
GetMetaChannel return true, if (and only if) the message is a MetaChannelMsg. Then it also extracts the channel to the given argument.
func (Message) GetMetaCopyright ¶
GetMetaCopyright return true, if (and only if) the message is a MetaCopyrightMsg. Then it also extracts the text to the given argument.
func (Message) GetMetaCuepoint ¶
GetMetaCuepoint return true, if (and only if) the message is a MetaCuepointMsg. Then it also extracts the text to the given argument.
func (Message) GetMetaDevice ¶
GetMetaDevice return true, if (and only if) the message is a MetaDeviceMsg. Then it also extracts the text to the given argument.
func (Message) GetMetaInstrument ¶
GetMetaInstrument return true, if (and only if) the message is a MetaInstrumentMsg. Then it also extracts the text to the given argument.
func (Message) GetMetaKey ¶
GetMetaKey is a handier wrapper around GetMetaKeySig. It returns nil if the message is no MetaKeySigMsg.
func (Message) GetMetaKeySig ¶
GetMetaKeySig return true, if (and only if) the message is a MetaKeySigMsg. Then it also extracts the data to the given argument.
func (Message) GetMetaLyric ¶
GetMetaLyric return true, if (and only if) the message is a MetaLyricMsg. Then it also extracts the text to the given argument.
func (Message) GetMetaMarker ¶
GetMetaMarker return true, if (and only if) the message is a MetaMarkerMsg. Then it also extracts the text to the given argument.
func (Message) GetMetaMeter ¶
GetMetaMeter is a handier wrapper around GetMetaTimeSig.
func (Message) GetMetaPort ¶
GetMetaPort return true, if (and only if) the message is a MetaPortMsg. Then it also extracts the port to the given argument.
func (Message) GetMetaProgramName ¶
GetMetaProgramName return true, if (and only if) the message is a MetaProgramNameMsg. Then it also extracts the text to the given argument.
func (Message) GetMetaSMPTEOffsetMsg ¶
GetMetaSMPTEOffsetMsg return true, if (and only if) the message is a MetaSMPTEOffsetMsg. Then it also extracts the data to the given arguments.
func (Message) GetMetaSeqData ¶
GetMetaSeqData return true, if (and only if) the message is a MetaSeqDataMsg. Then it also extracts the data to the given argument.
func (Message) GetMetaSeqNumber ¶
GetMetaSeqNumber return true, if (and only if) the message is a MetaSeqNumberMsg. Then it also extracts the sequenceNumber to the given argument.
func (Message) GetMetaTempo ¶
GetMetaTempo return true, if (and only if) the message is a MetaTempoMsg. Then it also extracts the BPM to the given argument.
func (Message) GetMetaText ¶
GetMetaText return true, if (and only if) the message is a MetaTextMsg. Then it also extracts the text to the given argument.
func (Message) GetMetaTimeSig ¶
func (m Message) GetMetaTimeSig(numerator, denominator, clocksPerClick, demiSemiQuaverPerQuarter *uint8) (is bool)
GetMetaTimeSig return true, if (and only if) the message is a MetaTimeSigMsg. Then it also extracts the data to the given arguments.
func (Message) GetMetaTrackName ¶
GetMetaTrackName return true, if (and only if) the message is a MetaTrackNameMsg. Then it also extracts the text to the given argument.
func (Message) GetNoteEnd ¶
GetNoteEnd returns true if (and only if) the message is a NoteOnMsg with a velocity == 0 or a NoteOffMsg. Then it also extracts the data to the given arguments
func (Message) GetNoteOff ¶
GetNoteOff returns true if (and only if) the message is a NoteOffMsg. Then it also extracts the data to the given arguments
func (Message) GetNoteOn ¶
GetNoteOn returns true if (and only if) the message is a NoteOnMsg. Then it also extracts the data to the given arguments
func (Message) GetNoteStart ¶
GetNoteStart returns true if (and only if) the message is a NoteOnMsg with a velocity > 0. Then it also extracts the data to the given arguments
func (Message) GetPitchBend ¶
GetPitchBend returns true if (and only if) the message is a PitchBendMsg. Then it also extracts the data to the given arguments Either relative or absolute may be nil, if not needed.
func (Message) GetPolyAfterTouch ¶
GetPolyAfterTouch returns true if (and only if) the message is a PolyAfterTouchMsg. Then it also extracts the data to the given arguments
func (Message) GetProgramChange ¶
GetProgramChange returns true if (and only if) the message is a ProgramChangeMsg. Then it also extracts the data to the given arguments
func (Message) GetSysEx ¶
GetSysEx returns true, if the message is a sysex message. Then it extracts the inner bytes to the given slice.
func (Message) IsPlayable ¶
IsPlayable returns true, if the message can be send to an instrument.
type MetricTicks ¶
type MetricTicks uint16
MetricTicks represents the "ticks per quarter note" (metric) time format. It defaults to 960 (i.e. 0 is treated as if it where 960 ticks per quarter note).
func (MetricTicks) Duration ¶
func (q MetricTicks) Duration(fractionalBPM float64, deltaTicks uint32) time.Duration
Duration returns the time.Duration for a number of ticks at a certain tempo (in fractional BPM)
func (MetricTicks) In64ths ¶
func (q MetricTicks) In64ths(deltaTicks uint32) uint32
In64ths returns the deltaTicks in 64th notes. To get 32ths, divide result by 2. To get 16ths, divide result by 4. To get 8ths, divide result by 8. To get 4ths, divide result by 16.
func (MetricTicks) Resolution ¶
func (q MetricTicks) Resolution() uint16
Resolution returns the number of the metric ticks (ticks for a quarter note, defaults to 960)
func (MetricTicks) String ¶
func (q MetricTicks) String() string
String returns the string representation of the quarter note resolution
func (MetricTicks) Ticks ¶
func (q MetricTicks) Ticks(fractionalBPM float64, d time.Duration) (ticks uint32)
Ticks returns the ticks for a given time.Duration at a certain tempo (in fractional BPM)
func (MetricTicks) Ticks1024th ¶
func (q MetricTicks) Ticks1024th() uint32
Ticks1024th returns the ticks for a 1024th note
func (MetricTicks) Ticks128th ¶
func (q MetricTicks) Ticks128th() uint32
Ticks128th returns the ticks for a 128th note
func (MetricTicks) Ticks16th ¶
func (q MetricTicks) Ticks16th() uint32
Ticks16th returns the ticks for a 16th note
func (MetricTicks) Ticks256th ¶
func (q MetricTicks) Ticks256th() uint32
Ticks256th returns the ticks for a 256th note
func (MetricTicks) Ticks32th ¶
func (q MetricTicks) Ticks32th() uint32
Ticks32th returns the ticks for a 32th note
func (MetricTicks) Ticks4th ¶
func (q MetricTicks) Ticks4th() uint32
Ticks4th returns the ticks for a quarter note
func (MetricTicks) Ticks512th ¶
func (q MetricTicks) Ticks512th() uint32
Ticks512th returns the ticks for a 512th note
func (MetricTicks) Ticks64th ¶
func (q MetricTicks) Ticks64th() uint32
Ticks64th returns the ticks for a 64th note
func (MetricTicks) Ticks8th ¶
func (q MetricTicks) Ticks8th() uint32
Ticks8th returns the ticks for a quaver note
type ReadOption ¶
type ReadOption func(*readConfig)
ReadOption is an option for reading of SMF files
func Log ¶
func Log(l Logger) ReadOption
type SMF ¶
type SMF struct { // NoRunningStatus is an option for writing to not write running status NoRunningStatus bool // Logger allows logging when reading or writing Logger Logger // TimeFormat is the time format (either MetricTicks or TimeCode). TimeFormat TimeFormat // Tracks contain the midi events Tracks []Track // contains filtered or unexported fields }
func New ¶
func New() *SMF
New returns a SMF file of format type 0 (single track), that becomes type 1 (multi track), if you add tracks
func ReadFile ¶
func ReadFile(file string, opts ...ReadOption) (*SMF, error)
ReadFile opens file, creates the SMF and closes file
func ReadFrom ¶
func ReadFrom(f io.Reader, opts ...ReadOption) (*SMF, error)
ReadFrom reads a SMF from the given io.Reader
func (SMF) ConvertToSMF1 ¶ added in v2.0.23
ConvertToSMF1 converts a given SMF format 0 to SMF format 1 channel messages are distributed over the tracks by their channels e.g. channel 0 -> track 1, channel 1 -> track 2 etc. and everything else stays in track 0
func (*SMF) RecordFrom ¶
RecordFrom records from the given midi in port into a new track. It returns a stop function that must be called to stop the recording. It is up to the user to save the SMF.
func (*SMF) TempoChanges ¶
func (s *SMF) TempoChanges() TempoChanges
func (*SMF) TimeAt ¶
TimeAt returns the absolute time for a given absolute tick (considering the tempo changes)
type TempoChange ¶
type TempoChanges ¶
type TempoChanges []*TempoChange
func (TempoChanges) Len ¶
func (t TempoChanges) Len() int
func (TempoChanges) Less ¶
func (t TempoChanges) Less(a, b int) bool
func (TempoChanges) Swap ¶
func (t TempoChanges) Swap(a, b int)
func (TempoChanges) TempoAt ¶
func (t TempoChanges) TempoAt(absTicks int64) (bpm float64)
func (TempoChanges) TempoChangeAt ¶
func (t TempoChanges) TempoChangeAt(absTicks int64) (tch *TempoChange)
type TimeCode ¶
TimeCode is the SMPTE time format. It can be comfortable created with the SMPTE* functions.
func SMPTE30DropFrame ¶
SMPTE30DropFrame returns a SMPTE30 drop frame TimeCode with the given subframes.
type TimeFormat ¶
type TimeFormat interface { String() string // contains filtered or unexported methods }
TimeFormat is the common interface of all SMF time formats
type Track ¶
type Track []Event
func (*Track) RecordFrom ¶
func (*Track) SendTo ¶
func (t *Track) SendTo(resolution MetricTicks, tc TempoChanges, receiver func(m midi.Message, timestampms int32))
type TrackEvents ¶ added in v2.0.23
type TrackEvents []*TrackEvent
func (TrackEvents) Len ¶ added in v2.0.23
func (b TrackEvents) Len() int
func (TrackEvents) Less ¶ added in v2.0.23
func (br TrackEvents) Less(a, b int) bool
func (TrackEvents) Swap ¶ added in v2.0.23
func (br TrackEvents) Swap(a, b int)
type TracksReader ¶
type TracksReader struct {
// contains filtered or unexported fields
}
func ReadTracks ¶
func ReadTracks(filepath string, tracks ...int) *TracksReader
func ReadTracksFrom ¶
func ReadTracksFrom(rd io.Reader, tracks ...int) *TracksReader
func (*TracksReader) Do ¶
func (t *TracksReader) Do(fn func(TrackEvent)) *TracksReader
func (*TracksReader) Error ¶
func (t *TracksReader) Error() error
func (*TracksReader) MultiPlay ¶
func (t *TracksReader) MultiPlay(trackouts map[int]drivers.Out) error
MultiPlay plays tracks to different out ports. If the map has an index of -1, it will be used to play all tracks that have no explicit out port.
func (*TracksReader) Only ¶
func (t *TracksReader) Only(mtypes ...midi.Type) *TracksReader
func (*TracksReader) Play ¶
func (t *TracksReader) Play(out drivers.Out) error
Play plays the tracks on the given out port
func (*TracksReader) SMF ¶
func (t *TracksReader) SMF() *SMF