Commit ad72649b authored by Jacob Vosmaer's avatar Jacob Vosmaer

Start creating commands

parent 507fea51
package main
import (
"fmt"
"log"
"os"
"jacobvosmaer.nl/go/dx7"
)
const (
progName = "dx7-ls"
)
func main() {
if len(os.Args) != 2 {
log.Fatalf("usage: %s [FILE]", progName)
}
f, err := os.Open(os.Args[1])
if err != nil {
log.Fatal(err)
}
defer f.Close()
msgs, err := dx7.SplitMessages(f)
if err != nil {
log.Fatal(err)
}
for _, msg := range msgs {
l := len(msg)
contents := fmt.Sprintf("% x ... % x", msg[:dx7.MinMessageLength], msg[l-2:l])
if l < 10 {
contents = fmt.Sprintf("% x", msg)
}
fmt.Printf("%s (%d bytes)\n", contents, l)
t, ok := dx7.Type(msg)
if ok {
fmt.Printf(" %s\n", t)
}
if ok && t == "packed 32 voice" {
data, err := dx7.Data(msg)
if err != nil {
log.Fatal(err)
}
for i := 0; i < 32; i++ {
fmt.Printf(" %q\n", data[i*128+118:(i+1)*128])
}
}
}
}
package main
import (
"fmt"
"io/ioutil"
"log"
"os"
"strings"
"jacobvosmaer.nl/go/dx7"
)
const (
progName = "dx7-split"
)
func main() {
if len(os.Args) != 2 {
log.Fatalf("usage: %s [FILE]", progName)
}
f, err := os.Open(os.Args[1])
if err != nil {
log.Fatal(err)
}
defer f.Close()
msgs, err := dx7.SplitMessages(f)
if err != nil {
log.Fatal(err)
}
count := 0
for _, msg := range msgs {
t, ok := dx7.Type(msg)
if !(ok && t == "packed 32 voice") {
continue
}
data, err := dx7.Data(msg)
if err != nil {
log.Fatal(err)
}
for i := 0; i < 32; i++ {
v := data[i*128 : (i+1)*128]
voiceName := string(v[118:128])
fileName := fmt.Sprintf("%03d-%s.d7v", count+1, strings.Replace(voiceName, "/", "_", -1))
fmt.Println(fileName)
if err := ioutil.WriteFile(fileName, v, 0644); err != nil {
log.Fatal(err)
}
count++
}
}
}
package dx7
import (
"bufio"
"bytes"
"fmt"
"io"
"strings"
)
const (
MinMessageLength = 4
)
func IsMk1(msg []byte) bool {
if len(msg) < 4 {
return false
}
if !bytes.Equal(msg[0:3], []byte{0xf0, 0x43, 0x00}) {
return false
}
return bytes.Contains([]byte{0x00, 0x05, 0x06, 0x09}, msg[3:4])
}
func DataLen(msb, lsb byte) int {
return (int(msb) << 7) + int(lsb)
}
func Checksum(data []byte) byte {
var sum byte
for _, b := range data {
sum = sum + b
}
return (128 - sum) & 0x7f
}
func IsPackedVoices(msg []byte) bool {
return bytes.Equal([]byte{0xf0, 0x43, 0x00, 0x09, 0x20, 0x00}, msg[0:6])
}
func SplitMessages(r io.Reader) ([][]byte, error) {
in := bufio.NewReader(r)
var msgs [][]byte
var err error
for {
var msg []byte
msg, err = in.ReadBytes(0xf7)
l := len(msg)
if err != nil || l == 0 {
break
}
if l < MinMessageLength {
return nil, fmt.Errorf("message too short: % x", msg)
}
if h := msg[:2]; !bytes.Equal(h, []byte{0xf0, 0x43}) {
return nil, fmt.Errorf("invalid sysex message start %x", h)
}
msgs = append(msgs, msg)
}
if err == io.EOF {
err = nil
}
return msgs, err
}
func Type(_msg []byte) (string, bool) {
msg := string(_msg)
if !strings.HasPrefix(msg, "\xf0\x43") {
return "", false
}
switch {
case msg[2:4] == "\x00\x00":
return "voice edit buffer", true
case msg[2:4] == "\x00\x05":
return "supplement edit buffer", true
case msg[2:4] == "\x00\x06":
return "packed 32 supplement", true
case msg[2:4] == "\x00\x09":
return "packed 32 voice", true
case msg[2:4] == "\x00\x7e":
if len(msg) < 18 {
return "", false
}
return msg[6:16], true
case msg[2:5] == "\x10\x19\x4d":
return "midi receive block", true
}
return "", false
}
func Data(msg []byte) ([]byte, error) {
if !IsMk1(msg) {
return nil, fmt.Errorf("unsupported")
}
l := len(msg)
if l < 8 {
return nil, fmt.Errorf("message too short: %d", l)
}
dataLen := DataLen(msg[4], msg[5])
if l != dataLen+8 {
return nil, fmt.Errorf("expected msg length %d, got %d", dataLen, l)
}
data := msg[6 : 6+dataLen]
sum := Checksum(data)
if exSum := msg[l-2]; sum != exSum {
return nil, fmt.Errorf("expected checksum %x, got %x", exSum, sum)
}
return data, nil
}
package main
package dx7
import (
"bufio"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment