From 2e012a6d9237e4cb285983ece2f467ed818bdce9 Mon Sep 17 00:00:00 2001 From: Terin Stock Date: Sat, 16 May 2020 16:01:56 -0700 Subject: feat(playsmf): support playback via rtmidi Add support for playback via rtmidi to support debugging on devices where a MIDI synthesizer is not connected via serial. --- cmd/playsmf/main.go | 77 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 53 insertions(+), 24 deletions(-) (limited to 'cmd/playsmf/main.go') diff --git a/cmd/playsmf/main.go b/cmd/playsmf/main.go index 7b55ff3..ca9e105 100644 --- a/cmd/playsmf/main.go +++ b/cmd/playsmf/main.go @@ -5,37 +5,64 @@ import ( "flag" "fmt" "os" + "strings" "time" "gitlab.com/gomidi/midi" - "gitlab.com/gomidi/midi/mid" "gitlab.com/gomidi/midi/midimessage" + "gitlab.com/gomidi/midi/reader" "gitlab.com/gomidi/midi/smf" + "gitlab.com/gomidi/midi/writer" + "gitlab.com/gomidi/rtmididrv" "go.terinstock.com/midifi/pkg/ttymididrv" ) var ( - drv mid.Driver + drv midi.Driver + rt string midiSerial string ) func init() { flag.StringVar(&midiSerial, "com", "", "The serial port of the MIDI synth") + flag.StringVar(&rt, "rt", "", "Connect to client:port with rtmidi") } func main() { flag.Parse() - drv = ttymididrv.New(midiSerial, 38400) - defer drv.Close() - outs, err := drv.Outs() - if err != nil { - fmt.Printf("err: %v\n", err) - os.Exit(-1) + var out midi.Out + if rt != "" { + rtdrv, err := rtmididrv.New() + if err != nil { + panic(err) + } + drv = rtdrv + + outs, err := rtdrv.Outs() + if err != nil { + fmt.Printf("err: %v\n", err) + os.Exit(-1) + } + + for _, _out := range outs { + if strings.Contains(_out.String(), rt) { + out = _out + break + } + } + } else { + drv = ttymididrv.New(midiSerial, 38400) + outs, err := drv.Outs() + if err != nil { + fmt.Printf("err: %v\n", err) + os.Exit(-1) + } + out = outs[0] } - out := outs[0] + defer drv.Close() - err = out.Open() + err := out.Open() if err != nil { fmt.Printf("err: %v\n", err) os.Exit(-1) @@ -56,24 +83,26 @@ func main() { fmt.Printf("file: %s\n", flag.Arg(0)) - mf := mid.NewReader(mid.NoLogger()) - mf.SMFHeader = func(header smf.Header) { - fmt.Printf("file format: %s\n", header.Format.String()) - fmt.Printf("number of tracks: %d\n", header.NumTracks) - fmt.Printf("time format: %s\n", header.TimeFormat.String()) - fmt.Println("===========") - } events := &list.List{} - mf.Msg.Each = func(pos *mid.Position, msg midi.Message) { - addEvent(events, Event{track: pos.Track, abs: pos.AbsoluteTicks, msg: msg}) - } - mf.ReadSMF(f) - - w := mid.WriteTo(out) + mf := reader.New( + reader.NoLogger(), + reader.SMFHeader(func(header smf.Header) { + fmt.Printf("file format: %s\n", header.Format.String()) + fmt.Printf("number of tracks: %d\n", header.NumTracks) + fmt.Printf("time format: %s\n", header.TimeFormat.String()) + fmt.Println("===========") + }), + reader.Each(func(pos *reader.Position, msg midi.Message) { + addEvent(events, Event{track: pos.Track, abs: pos.AbsoluteTicks, msg: msg}) + }), + ) + reader.ReadSMF(mf, f) + + w := writer.New(out) var lastDur time.Duration for event := events.Front(); event != nil; event = event.Next() { - dur := *mf.TimeAt(event.Value.(Event).abs) + dur := *reader.TimeAt(mf, event.Value.(Event).abs) if lastDur != dur { <-time.After(dur - lastDur) lastDur = dur -- cgit v1.2.3