go-midi
provides reading and writing standard MIDI file.
go get -u github.com/moutend/go-midi
The 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