summary refs log tree commit diff
diff options
context:
space:
mode:
authorTerin Stock <terinjokes@gmail.com>2020-05-16 16:01:56 -0700
committerTerin Stock <terinjokes@gmail.com>2020-05-16 16:03:13 -0700
commit2e012a6d9237e4cb285983ece2f467ed818bdce9 (patch)
treeea1a3ce26aec47144a92b967b7130a849dece5fd
parentca933d746ba16ef326d9b4ba85d51940ab9e8add (diff)
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.
-rw-r--r--Gopkg.lock104
-rw-r--r--Gopkg.toml29
-rw-r--r--cmd/playsmf/main.go77
-rw-r--r--go.mod14
-rw-r--r--go.sum20
-rw-r--r--pkg/ttymididrv/driver.go20
-rw-r--r--pkg/ttymididrv/out.go8
7 files changed, 103 insertions, 169 deletions
diff --git a/Gopkg.lock b/Gopkg.lock
deleted file mode 100644
index 6c7468d..0000000
--- a/Gopkg.lock
+++ /dev/null
@@ -1,104 +0,0 @@
-# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
-
-
-[[projects]]
-  digest = "1:2e3c336fc7fde5c984d2841455a658a6d626450b1754a854b3b32e7a8f49a07a"
-  name = "github.com/google/go-cmp"
-  packages = [
-    "cmp",
-    "cmp/internal/diff",
-    "cmp/internal/function",
-    "cmp/internal/value",
-  ]
-  pruneopts = "UT"
-  revision = "3af367b6b30c263d47e8895973edcca9a49cf029"
-  version = "v0.2.0"
-
-[[projects]]
-  digest = "1:40e195917a951a8bf867cd05de2a46aaf1806c50cf92eebf4c16f78cd196f747"
-  name = "github.com/pkg/errors"
-  packages = ["."]
-  pruneopts = "UT"
-  revision = "645ef00459ed84a119197bfb8d8205042c6df63d"
-  version = "v0.8.0"
-
-[[projects]]
-  branch = "master"
-  digest = "1:4f43b3c1b7e44980a5f3c593f8bf0e18844dc44f451a071c93e77e28cf990db6"
-  name = "github.com/pkg/term"
-  packages = ["termios"]
-  pruneopts = "UT"
-  revision = "cda20d4ac917ad418d86e151eff439648b06185b"
-
-[[projects]]
-  branch = "master"
-  digest = "1:b9b666a56e920eaa59ffea0d25a9b848d7073be13689c4a29d04e4a0f548a031"
-  name = "github.com/tarm/serial"
-  packages = ["."]
-  pruneopts = "UT"
-  revision = "eaafced92e9619f03c72527efeab21e326f3bc36"
-
-[[projects]]
-  digest = "1:60550785588e9d2a3afcb619b2cb92e802183bc0e53ec2aedaeefa2ebf6700d0"
-  name = "gitlab.com/gomidi/midi"
-  packages = [
-    ".",
-    "cc",
-    "internal/midilib",
-    "internal/runningstatus",
-    "internal/vlq",
-    "mid",
-    "midimessage",
-    "midimessage/channel",
-    "midimessage/meta",
-    "midimessage/meta/meter",
-    "midimessage/realtime",
-    "midimessage/syscommon",
-    "midimessage/sysex",
-    "midireader",
-    "midiwriter",
-    "smf",
-    "smf/smfreader",
-    "smf/smfwriter",
-  ]
-  pruneopts = "UT"
-  revision = "2499eaf73227fafd8e1ca0a625c569066835d695"
-  version = "v1.7.9"
-
-[[projects]]
-  branch = "master"
-  digest = "1:d773e525476aefa22ea944a5425a9bfb99819b2e67eeb9b1966454fd57522bbf"
-  name = "golang.org/x/sys"
-  packages = ["unix"]
-  pruneopts = "UT"
-  revision = "ac767d655b305d4e9612f5f6e33120b9176c4ad4"
-
-[[projects]]
-  digest = "1:23fe6c6a60e25700c53335117c4176780d207c7799958ad051d0a8b82b00efb6"
-  name = "gotest.tools"
-  packages = [
-    "assert",
-    "assert/cmp",
-    "golden",
-    "internal/difflib",
-    "internal/format",
-    "internal/source",
-  ]
-  pruneopts = "UT"
-  revision = "b6e20af1ed078cd01a6413b734051a292450b4cb"
-  version = "v2.1.0"
-
-[solve-meta]
-  analyzer-name = "dep"
-  analyzer-version = 1
-  input-imports = [
-    "github.com/pkg/term/termios",
-    "github.com/tarm/serial",
-    "gitlab.com/gomidi/midi",
-    "gitlab.com/gomidi/midi/mid",
-    "gitlab.com/gomidi/midi/midimessage",
-    "gitlab.com/gomidi/midi/smf",
-    "gotest.tools/golden",
-  ]
-  solver-name = "gps-cdcl"
-  solver-version = 1
diff --git a/Gopkg.toml b/Gopkg.toml
deleted file mode 100644
index 2765dc9..0000000
--- a/Gopkg.toml
+++ /dev/null
@@ -1,29 +0,0 @@
-# Gopkg.toml example
-#
-# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html
-# for detailed Gopkg.toml documentation.
-#
-# required = ["github.com/user/thing/cmd/thing"]
-# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
-#
-# [[constraint]]
-#   name = "github.com/user/project"
-#   version = "1.0.0"
-#
-# [[constraint]]
-#   name = "github.com/user/project2"
-#   branch = "dev"
-#   source = "github.com/myfork/project2"
-#
-# [[override]]
-#   name = "github.com/x/y"
-#   version = "2.4.0"
-#
-# [prune]
-#   non-go = false
-#   go-tests = true
-#   unused-packages = true
-
-[prune]
-  go-tests = true
-  unused-packages = true
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
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..3096343
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,14 @@
+module go.terinstock.com/midifi
+
+go 1.14
+
+require (
+	github.com/google/go-cmp v0.2.0 // indirect
+	github.com/pkg/errors v0.8.0 // indirect
+	github.com/pkg/term v0.0.0-20180423043932-cda20d4ac917
+	github.com/tarm/serial v0.0.0-20180114052751-eaafced92e96
+	gitlab.com/gomidi/midi v1.16.5
+	gitlab.com/gomidi/rtmididrv v0.10.1
+	golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f // indirect
+	gotest.tools v2.1.0+incompatible
+)
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..1af2417
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,20 @@
+github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
+github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
+github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
+github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/term v0.0.0-20180423043932-cda20d4ac917 h1:BinR73QvQveJdQ8uYZK/8MOjLADpZbI2qs/2+5rnhzQ=
+github.com/pkg/term v0.0.0-20180423043932-cda20d4ac917/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ=
+github.com/tarm/serial v0.0.0-20180114052751-eaafced92e96 h1:pLss0TM/G46eE2p8NIRYIlB12vrPvWXiqDoCKA52wwQ=
+github.com/tarm/serial v0.0.0-20180114052751-eaafced92e96/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
+gitlab.com/gomidi/midi v1.16.4 h1:Cl2HrJh+ww7ivNlxyKbhEI7q3j9nqv7y/FF+8KFwz3s=
+gitlab.com/gomidi/midi v1.16.4/go.mod h1:3ohtNOhqoSakkuLG/Li1OI6I3J1c2LErnJF5o/VBq1c=
+gitlab.com/gomidi/midi v1.16.5 h1:D+ytdzCobT4snvaXi4HxpKd3J5vhst8DsQWm5XlYn+I=
+gitlab.com/gomidi/midi v1.16.5/go.mod h1:3ohtNOhqoSakkuLG/Li1OI6I3J1c2LErnJF5o/VBq1c=
+gitlab.com/gomidi/rtmididrv v0.10.1 h1:BgqhFpBgythJqFbiR8QtL3CER1nh26YCUPFGVidS9gk=
+gitlab.com/gomidi/rtmididrv v0.10.1/go.mod h1:sBxBDsJKVhinLt+kk7fj6WfKRCmnFzFSkFY1chDNLbw=
+gitlab.com/gomidi/rtmididrv/imported/rtmidi v0.0.0-20191025100939-514fe0ed97a6 h1:0XqAH/BAxH5TTBzIWkdlZqpp6VUx6DFcQnMWW6G6hIc=
+gitlab.com/gomidi/rtmididrv/imported/rtmidi v0.0.0-20191025100939-514fe0ed97a6/go.mod h1:FYVFN2H23IsX56VntiDF9DgCIekHh359wW+iMl1W8rQ=
+golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f h1:gWF768j/LaZugp8dyS4UwsslYCYz9XgFxvlgsn0n9H8=
+golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+gotest.tools v2.1.0+incompatible h1:5USw7CrJBYKqjg9R7QlA6jzqZKEAtvW82aNmsxxGPxw=
+gotest.tools v2.1.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
diff --git a/pkg/ttymididrv/driver.go b/pkg/ttymididrv/driver.go
index cc7b1fd..f2282df 100644
--- a/pkg/ttymididrv/driver.go
+++ b/pkg/ttymididrv/driver.go
@@ -3,19 +3,19 @@ package ttymididrv
 import (
 	"sync"
 
-	"gitlab.com/gomidi/midi/mid"
+	"gitlab.com/gomidi/midi"
 )
 
 type driver struct {
 	mu     sync.RWMutex
-	outs   []mid.Out
-	opened []mid.Port
+	outs   []midi.Out
+	opened []midi.Port
 	closed bool
 }
 
-func New(name string, baud int) mid.Driver {
+func New(name string, baud int) midi.Driver {
 	d := &driver{}
-	d.outs = []mid.Out{
+	d.outs = []midi.Out{
 		&out{
 			name:   name,
 			baud:   baud,
@@ -35,7 +35,7 @@ func (d *driver) Close() (err error) {
 	d.mu.RLock()
 	if d.closed {
 		d.mu.RUnlock()
-		return mid.ErrClosed
+		return midi.ErrPortClosed
 	}
 	d.mu.RUnlock()
 
@@ -50,23 +50,23 @@ func (d *driver) Close() (err error) {
 	return
 }
 
-func (d *driver) Ins() ([]mid.In, error) {
+func (d *driver) Ins() ([]midi.In, error) {
 	d.mu.Lock()
 	defer d.mu.Unlock()
 
 	if d.closed {
-		return nil, mid.ErrClosed
+		return nil, midi.ErrPortClosed
 	}
 
 	return nil, nil
 }
 
-func (d *driver) Outs() ([]mid.Out, error) {
+func (d *driver) Outs() ([]midi.Out, error) {
 	d.mu.Lock()
 	defer d.mu.Unlock()
 
 	if d.closed {
-		return nil, mid.ErrClosed
+		return nil, midi.ErrPortClosed
 	}
 
 	return d.outs, nil
diff --git a/pkg/ttymididrv/out.go b/pkg/ttymididrv/out.go
index 3e16cff..4932190 100644
--- a/pkg/ttymididrv/out.go
+++ b/pkg/ttymididrv/out.go
@@ -1,6 +1,7 @@
 package ttymididrv
 
 import (
+	"fmt"
 	"sync"
 
 	"github.com/tarm/serial"
@@ -73,7 +74,10 @@ func (o *out) Underlying() interface{} {
 	return o.port
 }
 
-func (o *out) Send(b []byte) error {
+func (o *out) Write(b []byte) (int, error) {
 	_, err := o.port.Write(b)
-	return err
+	if err != nil {
+		return 0, fmt.Errorf("could not write to port: %w", err)
+	}
+	return len(b), nil
 }