smf

package
v2.2.5 Latest Latest
Warning

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

Go to latest
Published: Jul 30, 2024 License: MIT Imports: 18 Imported by: 61

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

Examples

Constants

View Source
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
)
View Source
const (
	MetaMsg midi.Type = -5
)

Variables

View Source
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")
)
View Source
var EOT = _MetaMessage(byteEndOfTrack, nil)

EOT is an End Of Track meta message. Don't use it directly.

Functions

func RecordTo

func RecordTo(inport drivers.In, bpm float64, filename string) (stop func() error, err error)

RecordTo records from the given midi in port into the given filename with the given tempo. It returns a stop function that must be called to stop the recording. The file is then completed and saved.

Types

type Event

type Event struct {
	Delta   uint32
	Message Message
}

type Key

type Key struct {
	Key     uint8
	Num     uint8
	IsMajor bool
	IsFlat  bool
}

func (Key) String

func (k Key) String() string

type Logger

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

func LogTo added in v2.1.0

func LogTo(wr io.Writer) Logger

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 AMaj

func AMaj() Message

AMaj returns the MIDI key signature meta message for A Major

func AMin

func AMin() Message

AMin returns the MIDI key signature meta message for A Minor

func AbMaj

func AbMaj() Message

AbMaj returns the MIDI key signature meta message for Ab Major

func BMaj

func BMaj() Message

BMaj returns the MIDI key signature meta message for B Major

func BMin

func BMin() Message

BMin returns the MIDI key signature meta message for B Minor

func BbMaj

func BbMaj() Message

BbMaj returns the MIDI key signature meta message for Bb Major

func BbMin

func BbMin() Message

BbMin returns the MIDI key signature meta message for Bb Minor

func CMaj

func CMaj() Message

CMaj returns the MIDI key signature meta message for C Major

func CMin

func CMin() Message

CMin returns the MIDI key signature meta message for C Minor

func CsharpMin

func CsharpMin() Message

CsharpMin returns the MIDI key signature meta message for C# Minor

func DMaj

func DMaj() Message

DMaj returns the MIDI key signature meta message for D Major

func DMin

func DMin() Message

DMin returns the MIDI key signature meta message for D Minor

func DbMaj

func DbMaj() Message

DbMaj returns the MIDI key signature meta message for Db Major

func DsharpMin

func DsharpMin() Message

DsharpMin returns the MIDI key signature meta message for D# Minor

func EMaj

func EMaj() Message

EMaj returns the MIDI key signature meta message for E Major

func EMin

func EMin() Message

EMin returns the MIDI key signature meta message for E Minor

func EbMaj

func EbMaj() Message

EbMaj returns the MIDI key signature meta message for Eb Major

func EbMin

func EbMin() Message

EbMin returns the MIDI key signature meta message for Eb Minor

func FMaj

func FMaj() Message

FMaj returns the MIDI key signature meta message for F Major

func FMin

func FMin() Message

FMin returns the MIDI key signature meta message for F 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 GMaj

func GMaj() Message

GMaj returns the MIDI key signature meta message for G Major

func GMin

func GMin() Message

GMin returns the MIDI key signature meta message for G Minor

func GbMaj

func GbMaj() Message

GbMaj returns the MIDI key signature meta message for Gb Major

func GsharpMin

func GsharpMin() Message

GsharpMin returns the MIDI key signature meta message for G# Minor

func MetaChannel

func MetaChannel(ch uint8) Message

MetaChannel returns a channel meta message

func MetaCopyright

func MetaCopyright(text string) Message

MetaCopyright returns a copyright meta message

func MetaCuepoint

func MetaCuepoint(text string) Message

MetaCuepoint returns a cuepoint meta message

func MetaDevice

func MetaDevice(text string) Message

MetaDevice returns a device meta message

func MetaInstrument

func MetaInstrument(text string) Message

MetaInstrument returns an instrument meta message

func MetaKey

func MetaKey(key uint8, isMajor bool, num uint8, isFlat bool) Message

MetaKey returns a key meta message.

func MetaLyric

func MetaLyric(text string) Message

MetaLyric returns a lyric meta message

func MetaMarker

func MetaMarker(text string) Message

MetaMarker returns a marker meta message

func MetaMeter

func MetaMeter(num, denom uint8) Message

MetaMeter returns a time signature meta message.

func MetaPort

func MetaPort(p uint8) Message

MetaPort returns a port meta message

func MetaProgram

func MetaProgram(text string) Message

MetaProgram returns a program meta message

func MetaSMPTE

func MetaSMPTE(hour, minute, second, frame, fractionalFrame byte) Message

MetaSMPTE returns a SMPTE meta message

func MetaSequenceNo

func MetaSequenceNo(no uint16) Message

MetaSequenceNo returns a sequence number meta message

func MetaSequencerData

func MetaSequencerData(data []byte) Message

MetaSequencerData returns a sequencer data meta message

func MetaTempo

func MetaTempo(bpm float64) Message

MetaTempo returns a tempo meta message for the given beats per minute.

func MetaText

func MetaText(text string) Message

MetaText returns a text meta message.

func MetaTimeSig

func MetaTimeSig(numerator, denominator, clocksPerClick, demiSemiQuaverPerQuarter uint8) Message

MetaTimeSig returns a time signature meta message.

func MetaTrackSequenceName

func MetaTrackSequenceName(text string) Message

MetaTrackSequenceName returns a track sequence name meta message.

func MetaUndefined added in v2.1.0

func MetaUndefined(typ byte, data []byte) Message

MetaUndefined returns an undefined meta message.

func (Message) Bytes

func (m Message) Bytes() []byte

Bytes return the underlying bytes of the message.

func (Message) GetAfterTouch

func (m Message) GetAfterTouch(channel, pressure *uint8) (is bool)

GetAfterTouch returns true if (and only if) the message is a AfterTouchMsg. Then it also extracts the data to the given arguments Only arguments that are not nil are parsed and filled.

func (Message) GetChannel

func (m Message) GetChannel(channel *uint8) (is bool)

GetChannel returns true if (and only if) the message is a ChannelMsg. Then it also extracts the data to the given arguments Only arguments that are not nil are parsed and filled.

func (Message) GetControlChange

func (m Message) GetControlChange(channel, controller, value *uint8) (is bool)

GetControlChange returns true if (and only if) the message is a ControlChangeMsg. Then it also extracts the data to the given arguments Only arguments that are not nil are parsed and filled.

func (Message) GetMetaChannel

func (m Message) GetMetaChannel(channel *uint8) bool

GetMetaChannel return true, if (and only if) the message is a MetaChannelMsg. Then it also extracts the channel to the given argument. Only arguments that are not nil are parsed and filled.

func (Message) GetMetaCopyright

func (m Message) GetMetaCopyright(text *string) (is bool)

GetMetaCopyright return true, if (and only if) the message is a MetaCopyrightMsg. Then it also extracts the text to the given argument. Only arguments that are not nil are parsed and filled.

func (Message) GetMetaCuepoint

func (m Message) GetMetaCuepoint(text *string) (is bool)

GetMetaCuepoint return true, if (and only if) the message is a MetaCuepointMsg. Then it also extracts the text to the given argument. Only arguments that are not nil are parsed and filled.

func (Message) GetMetaDevice

func (m Message) GetMetaDevice(text *string) (is bool)

GetMetaDevice return true, if (and only if) the message is a MetaDeviceMsg. Then it also extracts the text to the given argument. Only arguments that are not nil are parsed and filled.

func (Message) GetMetaInstrument

func (m Message) GetMetaInstrument(text *string) (is bool)

GetMetaInstrument return true, if (and only if) the message is a MetaInstrumentMsg. Then it also extracts the text to the given argument. Only arguments that are not nil are parsed and filled.

func (Message) GetMetaKey

func (m Message) GetMetaKey(key *Key) bool

GetMetaKey is a handier wrapper around GetMetaKeySig. It returns nil if the message is no MetaKeySigMsg. Only arguments that are not nil are parsed and filled.

func (Message) GetMetaKeySig

func (m Message) GetMetaKeySig(key, num *uint8, isMajor *bool, isFlat *bool) bool

GetMetaKeySig return true, if (and only if) the message is a MetaKeySigMsg. Then it also extracts the data to the given argument. Only arguments that are not nil are parsed and filled.

func (Message) GetMetaLyric

func (m Message) GetMetaLyric(text *string) (is bool)

GetMetaLyric return true, if (and only if) the message is a MetaLyricMsg. Then it also extracts the text to the given argument. Only arguments that are not nil are parsed and filled.

func (Message) GetMetaMarker

func (m Message) GetMetaMarker(text *string) (is bool)

GetMetaMarker return true, if (and only if) the message is a MetaMarkerMsg. Then it also extracts the text to the given argument. Only arguments that are not nil are parsed and filled.

func (Message) GetMetaMeter

func (m Message) GetMetaMeter(num, denom *uint8) (is bool)

GetMetaMeter is a handier wrapper around GetMetaTimeSig. Only arguments that are not nil are parsed and filled.

func (Message) GetMetaPort

func (m Message) GetMetaPort(port *uint8) bool

GetMetaPort return true, if (and only if) the message is a MetaPortMsg. Then it also extracts the port to the given argument. Only arguments that are not nil are parsed and filled.

func (Message) GetMetaProgramName

func (m Message) GetMetaProgramName(text *string) (is bool)

GetMetaProgramName return true, if (and only if) the message is a MetaProgramNameMsg. Then it also extracts the text to the given argument. Only arguments that are not nil are parsed and filled.

func (Message) GetMetaSMPTEOffsetMsg

func (m Message) GetMetaSMPTEOffsetMsg(hour, minute, second, frame, fractframe *uint8) bool

GetMetaSMPTEOffsetMsg return true, if (and only if) the message is a MetaSMPTEOffsetMsg. Then it also extracts the data to the given arguments. Only arguments that are not nil are parsed and filled.

func (Message) GetMetaSeqData

func (m Message) GetMetaSeqData(bt *[]byte) bool

GetMetaSeqData return true, if (and only if) the message is a MetaSeqDataMsg. Then it also extracts the data to the given argument. Only arguments that are not nil are parsed and filled.

func (Message) GetMetaSeqNumber

func (m Message) GetMetaSeqNumber(sequenceNumber *uint16) bool

GetMetaSeqNumber return true, if (and only if) the message is a MetaSeqNumberMsg. Then it also extracts the sequenceNumber to the given argument. Only arguments that are not nil are parsed and filled.

func (Message) GetMetaTempo

func (m Message) GetMetaTempo(bpm *float64) (is bool)

GetMetaTempo return true, if (and only if) the message is a MetaTempoMsg. Then it also extracts the BPM to the given argument. Only arguments that are not nil are parsed and filled.

func (Message) GetMetaText

func (m Message) GetMetaText(text *string) (is bool)

GetMetaText return true, if (and only if) the message is a MetaTextMsg. Then it also extracts the text to the given argument. Only arguments that are not nil are parsed and filled.

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. Only arguments that are not nil are parsed and filled.

func (Message) GetMetaTrackName

func (m Message) GetMetaTrackName(text *string) (is bool)

GetMetaTrackName return true, if (and only if) the message is a MetaTrackNameMsg. Then it also extracts the text to the given argument. Only arguments that are not nil are parsed and filled.

func (Message) GetNoteEnd

func (m Message) GetNoteEnd(channel, key *uint8) (is bool)

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 Only arguments that are not nil are parsed and filled.

func (Message) GetNoteOff

func (m Message) GetNoteOff(channel, key, velocity *uint8) (is bool)

GetNoteOff returns true if (and only if) the message is a NoteOffMsg. Then it also extracts the data to the given arguments Only arguments that are not nil are parsed and filled.

func (Message) GetNoteOn

func (m Message) GetNoteOn(channel, key, velocity *uint8) (is bool)

GetNoteOn returns true if (and only if) the message is a NoteOnMsg. Then it also extracts the data to the given arguments Only arguments that are not nil are parsed and filled.

func (Message) GetNoteStart

func (m Message) GetNoteStart(channel, key, velocity *uint8) (is bool)

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 Only arguments that are not nil are parsed and filled.

func (Message) GetPitchBend

func (m Message) GetPitchBend(channel *uint8, relative *int16, absolute *uint16) (is bool)

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. Only arguments that are not nil are parsed and filled.

func (Message) GetPolyAfterTouch

func (m Message) GetPolyAfterTouch(channel, key, pressure *uint8) (is bool)

GetPolyAfterTouch returns true if (and only if) the message is a PolyAfterTouchMsg. Then it also extracts the data to the given arguments Only arguments that are not nil are parsed and filled.

func (Message) GetProgramChange

func (m Message) GetProgramChange(channel, program *uint8) (is bool)

GetProgramChange returns true if (and only if) the message is a ProgramChangeMsg. Then it also extracts the data to the given arguments Only arguments that are not nil are parsed and filled.

func (Message) GetSysEx

func (m Message) GetSysEx(bt *[]byte) bool

GetSysEx returns true, if the message is a sysex message. Then it extracts the inner bytes to the given slice. Only arguments that are not nil are parsed and filled.

func (Message) Is

func (m Message) Is(t midi.Type) bool

Is returns true, if the message is of the given type.

func (Message) IsMeta

func (m Message) IsMeta() bool

IsMeta returns true, if the message is a meta message.

func (Message) IsOneOf

func (m Message) IsOneOf(checkers ...midi.Type) bool

IsOneOf returns true, if the message is one of the given types.

func (Message) IsPlayable

func (m Message) IsPlayable() bool

IsPlayable returns true, if the message can be send to an instrument.

func (Message) String

func (m Message) String() string

String represents the Message as a string that contains the Type and its properties.

func (Message) Type

func (m Message) Type() midi.Type

Type returns the type of the message.

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 NewSMF1

func NewSMF1() *SMF

NewSMF1 returns a SMF file of format type 1 (multi track)

func NewSMF2

func NewSMF2() *SMF

NewSMF2 returns a SMF file of format type 2 (multi sequence)

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) Add

func (s *SMF) Add(t Track) error

Add adds a track to the SMF and returns an error, if the track is not closed.

func (SMF) ConvertToSMF1 added in v2.0.23

func (src SMF) ConvertToSMF1() (dest SMF)

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) Format

func (s SMF) Format() uint16

func (*SMF) NumTracks

func (s *SMF) NumTracks() uint16

NumTracks returns the number of tracks

func (*SMF) RecordFrom

func (s *SMF) RecordFrom(inport drivers.In, bpm float64) (stop func(), err error)

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) String added in v2.0.23

func (s SMF) String() string

func (*SMF) TempoChanges

func (s *SMF) TempoChanges() TempoChanges

func (*SMF) TimeAt

func (s *SMF) TimeAt(absTicks int64) (absTimeMicroSec int64)

TimeAt returns the absolute time for a given absolute tick (considering the tempo changes)

func (*SMF) WriteFile

func (s *SMF) WriteFile(file string) error

WriteFile writes the SMF to the given filename

func (*SMF) WriteTo

func (s *SMF) WriteTo(f io.Writer) (size int64, err error)

WriteTo writes the SMF to the given writer

type TempoChange

type TempoChange struct {
	AbsTicks        int64
	AbsTimeMicroSec int64
	BPM             float64
}

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

type TimeCode struct {
	FramesPerSecond uint8
	SubFrames       uint8
}

TimeCode is the SMPTE time format. It can be comfortable created with the SMPTE* functions.

func SMPTE24

func SMPTE24(subframes uint8) TimeCode

SMPTE24 returns a SMPTE24 TimeCode with the given subframes.

func SMPTE25

func SMPTE25(subframes uint8) TimeCode

SMPTE25 returns a SMPTE25 TimeCode with the given subframes.

func SMPTE30

func SMPTE30(subframes uint8) TimeCode

SMPTE30 returns a SMPTE30 TimeCode with the given subframes.

func SMPTE30DropFrame

func SMPTE30DropFrame(subframes uint8) TimeCode

SMPTE30DropFrame returns a SMPTE30 drop frame TimeCode with the given subframes.

func (TimeCode) String

func (t TimeCode) String() string

String represents the TimeCode as a string.

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) Add

func (t *Track) Add(deltaticks uint32, msgs ...[]byte)

func (*Track) Close

func (t *Track) Close(deltaticks uint32)

func (Track) IsClosed

func (t Track) IsClosed() bool

func (Track) IsEmpty

func (t Track) IsEmpty() bool

func (*Track) RecordFrom

func (t *Track) RecordFrom(inPort drivers.In, ticks MetricTicks, bpm float64) (stop func(), err error)

func (*Track) SendTo

func (t *Track) SendTo(resolution MetricTicks, tc TempoChanges, receiver func(m midi.Message, timestampms int32))

type TrackEvent

type TrackEvent struct {
	Event
	TrackNo         int
	AbsTicks        int64
	AbsMicroSeconds int64
}

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

Jump to

Keyboard shortcuts

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