smfreader

package
v1.23.7 Latest Latest
Warning

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

Go to latest
Published: May 26, 2021 License: MIT Imports: 12 Imported by: 3

Documentation

Overview

Package smfreader provides a reader of Standard MIDI Files (SMF).

Usage

import (
	"gitlab.com/gomidi/midi/smf/smfreader"
	. "gitlab.com/gomidi/midi/midimessage/channel"    // (Channel Messages)

	// you may also want to use these
	// gitlab.com/gomidi/midi/midimessage/meta       (Meta Messages)
	// gitlab.com/gomidi/midi/midimessage/cc         (Control Change Messages)
	// gitlab.com/gomidi/midi/midimessage/syscommon  (System Common Messages)
	// gitlab.com/gomidi/midi/midimessage/sysex      (System Exclusive Messages)
)

var err error

readMIDI := func (rd smf.Reader) {

	var m midi.Message

	for {
		m, err = rd.Read()

		// at the end smf.ErrFinished will be returned
		if err != nil {
			break
		}

		// deal with them based on a type switch
		switch msg := m.(type) {
		case NoteOn:
			fmt.Printf(
			  "NoteOn at channel %v: key %v velocity: %v\n",
			  msg.Channel(), // MIDI channels 1-16 correspond to msg.Channel 0-15
			  msg.Key(),
			  msg.Velocity(),
			)
		case NoteOff:
			...
		}
	}

}

smfreader.ReadFile("file.mid", readMIDI)

if err != smf.ErrFinished {
   // real error happened
}
Example
package main

import (
	"bytes"
	"fmt"
	"io"

	"gitlab.com/gomidi/midi"
	. "gitlab.com/gomidi/midi/midimessage/channel"
	"gitlab.com/gomidi/midi/midimessage/meta"
	"gitlab.com/gomidi/midi/smf"
	"gitlab.com/gomidi/midi/smf/smfreader"
	"gitlab.com/gomidi/midi/smf/smfwriter"
)

func mkMIDI() io.Reader {
	var bf bytes.Buffer

	wr := smfwriter.New(&bf)
	wr.Write(Channel2.Pitchbend(5000))
	wr.Write(Channel2.NoteOn(65, 90))
	wr.SetDelta(2)
	wr.Write(Channel2.NoteOff(65))
	wr.SetDelta(4)
	wr.Write(meta.EndOfTrack)
	return bytes.NewReader(bf.Bytes())
}

func main() {
	fmt.Println()

	rd := smfreader.New(mkMIDI())

	var m midi.Message
	var err error

	for {
		m, err = rd.Read()

		// at the end, smf.ErrFinished will be returned
		if err != nil {
			break
		}

		// inspect
		fmt.Println(rd.Delta(), m)

		switch v := m.(type) {
		case NoteOn:
			fmt.Printf("[%v] NoteOn at channel %v: key %v velocity %v\n", rd.Delta(), v.Channel(), v.Key(), v.Velocity())
		case NoteOff:
			fmt.Printf("[%v] NoteOff at channel %v: key %v\n", rd.Delta(), v.Channel(), v.Key())
		}

	}

	if err != smf.ErrFinished {
		panic("error: " + err.Error())
	}

}
Output:

0 channel.Pitchbend channel 2 value 5000 absValue 13192
0 channel.NoteOn channel 2 key 65 velocity 90
[0] NoteOn at channel 2: key 65 velocity 90
2 channel.NoteOff channel 2 key 65
[2] NoteOff at channel 2: key 65
4 meta.EndOfTrack

Index

Examples

Constants

This section is empty.

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

Functions

func New

func New(src io.Reader, opts ...Option) smf.Reader

New returns a smf.Reader

func ReadFile

func ReadFile(file string, callback func(smf.Reader), options ...Option) error

ReadFile opens file, calls callback with a reader and closes file

Types

type Option

type Option func(*reader)

Option is an option for the Reader

func NoteOffVelocity

func NoteOffVelocity() Option

NoteOffVelocity lets the reader differentiate between "fake" noteoff messages (which are in fact noteon messages (typ 9) with velocity of 0) and "real" noteoff messages (typ 8) that have a velocity. The former are returned as NoteOffVelocity messages and keep the given velocity, the later are returned as NoteOff messages without velocity. That means in order to get all noteoff messages, there must be checks for NoteOff and NoteOffVelocity (if this option is set). If this option is not set, both kinds are returned as NoteOff (default).

Jump to

Keyboard shortcuts

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