go-midi provides reading and writing standard MIDI file.
go get -u github.com/moutend/go-midiThe following program reads a file named music.mid and then prints all text data.
package main
import (
"fmt"
"io/ioutil"
midi "github.com/moutend/go-midi"
)
func main() {
file, err := ioutil.ReadFile("music.mid")
if err != nil {
panic(err)
}
midiData, err := midi.Parse(file)
if err != nil {
panic(err)
}
for _, track := range midiData.Tracks {
for _, event := range track.Events {
switch event.(type) {
case *midi.TextEvent:
fmt.Printf("%s\n", event.(*midi.TextEvent).Text())
}
}
}
}The following program reads a file named input.mid, set the velocity of all note-on events to 127 and creates a new file named output.mid.
package main
import (
"io/ioutil"
midi "github.com/moutend/go-midi"
)
func main() {
file, err := ioutil.ReadFile("input.mid")
if err != nil {
panic(err)
}
midiData, err := midi.Parse(file)
if err != nil {
panic(err)
}
for _, track := range midiData.Tracks {
for _, event := range track.Events {
switch event.(type) {
case *midi.NoteOnEvent:
event.(*midi.NoteOnEvent).SetVelocity(127)
}
}
}
err = ioutil.WriteFile("output.mid", midiData.Serialize(), 0644)
if err != nil {
panic(err)
}
}The following program creates a MIDI file which plays C major chord.
package main
import (
"io/ioutil"
midi "github.com/moutend/go-midi"
)
func main() {
deltaTime1, _ := midi.NewDeltaTime(0)
deltaTime2, _ := midi.NewDeltaTime(960)
noteOnC4, _ := midi.NewNoteOnEvent(deltaTime1, 0, midi.C4, 127)
noteOnE4, _ := midi.NewNoteOnEvent(deltaTime1, 0, midi.E4, 127)
noteOnG4, _ := midi.NewNoteOnEvent(deltaTime1, 0, midi.G4, 127)
noteOffC4, _ := midi.NewNoteOffEvent(deltaTime2, 0, midi.C4, 0)
noteOffE4, _ := midi.NewNoteOffEvent(deltaTime1, 0, midi.E4, 0)
noteOffG4, _ := midi.NewNoteOffEvent(deltaTime1, 0, midi.G4, 0)
endOfTrack, _ := midi.NewEndOfTrackEvent(deltaTime2)
track := &midi.Track{
Events: make([]midi.Event, 0),
}
track.Events = append(track.Events, noteOnC4)
track.Events = append(track.Events, noteOnE4)
track.Events = append(track.Events, noteOnG4)
track.Events = append(track.Events, noteOffC4)
track.Events = append(track.Events, noteOffE4)
track.Events = append(track.Events, noteOffG4)
track.Events = append(track.Events, endOfTrack)
m := midi.MIDI{}
m.TimeDivision().SetBPM(240)
m.Tracks = make([]*midi.Track, 1)
m.Tracks[0] = track
ioutil.WriteFile("oo.mid", m.Serialize(), 0644)
}There are two conventions for notes in MIDI. The most common is where C3 is 0x3c and the another is where C4 is 0x3c. In this package, where C3 is 0x3c.
The MIDI files located at testdata were composed by Nao. Check her great works:
- MIDI File Format Specifications · colxi/midi-parser-js Wiki
- 0xff21 and 0xff20 in MIDI
- OpenMIDIProject - Documentations
- Fork (https://github.com/moutend/go-midi/fork)
- Create a feature branch
- Add changes
- Run
go fmt - Commit your changes
- Open a new Pull Request
MIT