smfwriter

package
v1.10.3 Latest Latest
Warning

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

Go to latest
Published: Feb 28, 2019 License: MIT Imports: 10 Imported by: 8

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

func New(dest io.Writer, opts ...Option) smf.Writer

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

func WriteFile(file string, callback func(smf.Writer), options ...Option) error

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 Logger added in v1.8.5

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

type Option

type Option func(*writer)

Option is a Writer option

func Debug added in v1.8.5

func Debug(l Logger) Option

func Format

func Format(f smf.Format) Option

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

func NumTracks(ntracks uint16) Option

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.

Jump to

Keyboard shortcuts

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