Documentation
¶
Overview ¶
Package smfwriter provides a writer of Standard MIDI Files (SMF).
Usage
import ( "gitlab.com/gomidi/midi/smf" "gitlab.com/gomidi/midi/smf/smfwriter" "gitlab.com/gomidi/midi/midimessage/meta" // (Meta Messages) . "gitlab.com/gomidi/midi/midimessage/channel" // (Channel Messages) // you may also want to use these // gitlab.com/gomidi/midi/midimessage/cc (ControlChange Messages) // gitlab.com/gomidi/midi/midimessage/sysex (System Exclusive Messages) ) var err error tpq := smf.MetricTicks(0) // set the time resolution in ticks per quarter note; 0 uses the defaults (i.e. 960) writeMIDI := func (wr smf.Writer) { // always set the delta before writing wr.SetDelta(tpq.Ticks8th()) // starts MIDI key 65 on MIDI channel 3 with velocity 90 with delta of 480 to // the beginning of the track (note starts after a quaver pause) // MIDI channels 1-16 correspond to channel.Channel0 - channel.Channel15. err = wr.Write(Channel2.NoteOn(65, 90)) if err != nil { return } wr.SetDelta(tpq.Ticks4th()) // stops MIDI note 65 on MIDI channel 3 with delta of 960 to previous message // this results in a duration of 1 quarter note for midi note 65 err = wr.Write(Channel2.NoteOff(65)) if err != nil { return } // finishes the first track and writes it to the file err = wr.Write(meta.EndOfTrack) if err != nil { return } // the next write writes to the second track // after writing delta is always 0, so we start here at the beginning of the second track err = wr.Write(meta.Text("hello second track!")) if err != nil { return } // finishes the second track and writes it to the file err = wr.Write(meta.EndOfTrack) } // the number passed to the NumTracks option must match the tracks written // if NumTracks is not passed, it defaults to single track (SMF0) // if numtracks > 1, SMF1 format is chosen. // if TimeFormat is not passed, smf.MetricTicks(960) will be chosen smfwriter.WriteFile("file.mid", writeMIDI, smfwriter.NumTracks(2), smfwriter.TimeFormat(tpq)) // deal with err
Example ¶
fmt.Println() var bf bytes.Buffer wr := smfwriter.New(&bf) wr.Write(Channel2.Pitchbend(5000)) wr.SetDelta(2) wr.Write(Channel2.NoteOn(65, 90)) wr.SetDelta(4) wr.Write(Channel2.NoteOff(65)) wr.Write(meta.EndOfTrack) rd := smfreader.New(bytes.NewReader(bf.Bytes())) var m midi.Message var err error for { m, err = rd.Read() // breaking at least with io.EOF if err != nil { break } // inspect fmt.Println(rd.Delta(), m) switch v := m.(type) { case NoteOn: fmt.Printf("NoteOn at channel %v: key %v velocity: %v\n", v.Channel(), v.Key(), v.Velocity()) case NoteOff: fmt.Printf("NoteOff at channel %v: key %v\n", v.Channel(), v.Key()) } }
Output: 0 channel.Pitchbend channel 2 value 5000 absValue 13192 2 channel.NoteOn channel 2 key 65 velocity 90 NoteOn at channel 2: key 65 velocity: 90 4 channel.NoteOff channel 2 key 65 NoteOff at channel 2: key 65 0 meta.EndOfTrack
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func New ¶
New returns a Writer
The writer just uses an io.Writer..It is the responsibility of the caller to open and close any file where appropriate.
For the documentation of the Write and the SetDelta method, consult the documentation for smf.Writer.
The options and their defaults are documented at the corresponding option. When New returns, the header has already been written to dest. Any error that happened during the header writing is returned. In this case writer is nil.
func WriteFile ¶
WriteFile creates file, calls callback with a writer and closes file
WriteFile makes sure that the data of the last track is written by sending an meta.EndOfTrack message after callback has been run.
For single track (SMF0) files this makes sense since no meta.EndOfTrack message must then be send from callback (although it does not harm).
For multitrack files however there must be sending of meta.EndOfTrack anyway, so it is better practise to send it after each track (including the last one). The options and their defaults are the same as for New and they are documented at the corresponding option. The callback may call the given writer to write messages. If any of this write results in an error, the file won't be written and the error is returned. Only a successful write will manifest itself in the file being created.
Types ¶
type Option ¶
type Option func(*writer)
Option is a Writer option
func Format ¶
Format sets the SMF file format version. Valid values are: smf.SMF0 (single track), smf.SMF1 (multi track), smf.SMF2 (sequential track) If this option is not given, SMF0 will be used as default if the number of tracks is 1, otherwise SMF1.
func NoRunningStatus ¶
func NoRunningStatus() Option
NoRunningStatus forces the writer to always write the status byte. Without passing this option, running status will be used if possible (saving some bytes).
func NumTracks ¶
NumTracks sets the number of tracks in the file. Due to the SMF format and for performance reasons, the number of tracks must be given to Writer, before the MIDI events could be written. If the number of tracks is not given - or 0 - , it defaults to 1 track. If the given number of tracks has been written, any further writing returns an io.EOF error.
func TimeFormat ¶
func TimeFormat(timeformat smf.TimeFormat) Option
TimeFormat sets the timeformat. Allowed values are smf.MetricTicks and smf.TimeCode Without passing this option or when timeformat is nil, smf.MetricTicks(960) will be used.