From 3809ddbd239f312e9a05a33d5f77794df1c23dc5 Mon Sep 17 00:00:00 2001 From: twystd Date: Mon, 19 Aug 2024 20:04:19 -0700 Subject: [PATCH] midi: combined metaevent status + event bytes --- format/midi/TODO.md | 3 +- format/midi/metaevents.go | 80 ++++++++++++------------ format/midi/testdata/keys.fqtest | 104 +++++++++++-------------------- format/midi/testdata/test.fqtest | 22 +++---- 4 files changed, 86 insertions(+), 123 deletions(-) diff --git a/format/midi/TODO.md b/format/midi/TODO.md index e1fafc86..dd718dea 100644 --- a/format/midi/TODO.md +++ b/format/midi/TODO.md @@ -48,7 +48,7 @@ - [x] sequencer specific event - [x] map manufacturer - [x] check key mappings - - [ ] Combine status + event into metaevent field + - [x] Combine status + event into metaevent field - midi events - [x] note off @@ -68,5 +68,6 @@ - [x] escape - [x] use context struct for casio - [x] map manufacturer ID + - [ ] Decode status as 'sysex' diff --git a/format/midi/metaevents.go b/format/midi/metaevents.go index 86b3628b..8dd5aadd 100644 --- a/format/midi/metaevents.go +++ b/format/midi/metaevents.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/wader/fq/pkg/decode" + "github.com/wader/fq/pkg/scalar" ) type MetaEventType uint8 @@ -29,6 +30,27 @@ const ( TypeSequencerSpecificEvent MetaEventType = 0x7f ) +var metaevents = scalar.UintMapSymUint{ + 0xff00: 0x00, + 0xff01: 0x01, + 0xff02: 0x02, + 0xff03: 0x03, + 0xff04: 0x04, + 0xff05: 0x05, + 0xff06: 0x06, + 0xff07: 0x07, + 0xff08: 0x08, + 0xff09: 0x09, + 0xff20: 0x20, + 0xff21: 0x21, + 0xff51: 0x51, + 0xff54: 0x54, + 0xff58: 0x58, + 0xff59: 0x59, + 0xff2f: 0x2f, + 0xff7f: 0x7f, +} + func decodeMetaEvent(d *decode.D, event uint8, ctx *context) { ctx.running = 0x00 ctx.casio = false @@ -95,8 +117,7 @@ func decodeMetaEvent(d *decode.D, event uint8, ctx *context) { func decodeSequenceNumber(d *decode.D) { d.FieldUintFn("delta", vlq) - d.FieldU8("status") - d.FieldU8("event") + d.FieldU16("metaevent", metaevents) d.FieldUintFn("sequenceNumber", func(d *decode.D) uint64 { data := vlf(d) seqno := uint64(0) @@ -116,8 +137,7 @@ func decodeSequenceNumber(d *decode.D) { func decodeText(d *decode.D) { d.FieldUintFn("delta", vlq) - d.FieldU8("status") - d.FieldU8("event") + d.FieldU16("metaevent", metaevents) d.FieldStrFn("text", func(d *decode.D) string { return string(vlf(d)) }) @@ -125,8 +145,7 @@ func decodeText(d *decode.D) { func decodeCopyright(d *decode.D) { d.FieldUintFn("delta", vlq) - d.FieldU8("status") - d.FieldU8("event") + d.FieldU16("metaevent", metaevents) d.FieldStrFn("copyright", func(d *decode.D) string { return string(vlf(d)) }) @@ -134,8 +153,7 @@ func decodeCopyright(d *decode.D) { func decodeTrackName(d *decode.D) { d.FieldUintFn("delta", vlq) - d.FieldU8("status") - d.FieldU8("event") + d.FieldU16("metaevent", metaevents) d.FieldStrFn("name", func(d *decode.D) string { return string(vlf(d)) }) @@ -143,8 +161,7 @@ func decodeTrackName(d *decode.D) { func decodeInstrumentName(d *decode.D) { d.FieldUintFn("delta", vlq) - d.FieldU8("status") - d.FieldU8("event") + d.FieldU16("metaevent", metaevents) d.FieldStrFn("instrument", func(d *decode.D) string { return string(vlf(d)) }) @@ -152,8 +169,7 @@ func decodeInstrumentName(d *decode.D) { func decodeLyric(d *decode.D) { d.FieldUintFn("delta", vlq) - d.FieldU8("status") - d.FieldU8("event") + d.FieldU16("metaevent", metaevents) d.FieldStrFn("lyric", func(d *decode.D) string { return string(vlf(d)) }) @@ -161,8 +177,7 @@ func decodeLyric(d *decode.D) { func decodeMarker(d *decode.D) { d.FieldUintFn("delta", vlq) - d.FieldU8("status") - d.FieldU8("event") + d.FieldU16("metaevent", metaevents) d.FieldStrFn("marker", func(d *decode.D) string { return string(vlf(d)) }) @@ -170,8 +185,7 @@ func decodeMarker(d *decode.D) { func decodeCuePoint(d *decode.D) { d.FieldUintFn("delta", vlq) - d.FieldU8("status") - d.FieldU8("event") + d.FieldU16("metaevent", metaevents) d.FieldStrFn("cue", func(d *decode.D) string { return string(vlf(d)) }) @@ -179,8 +193,7 @@ func decodeCuePoint(d *decode.D) { func decodeProgramName(d *decode.D) { d.FieldUintFn("delta", vlq) - d.FieldU8("status") - d.FieldU8("event") + d.FieldU16("metaevent", metaevents) d.FieldStrFn("program", func(d *decode.D) string { return string(vlf(d)) }) @@ -188,8 +201,7 @@ func decodeProgramName(d *decode.D) { func decodeDeviceName(d *decode.D) { d.FieldUintFn("delta", vlq) - d.FieldU8("status") - d.FieldU8("event") + d.FieldU16("metaevent", metaevents) d.FieldStrFn("device", func(d *decode.D) string { return string(vlf(d)) }) @@ -197,8 +209,7 @@ func decodeDeviceName(d *decode.D) { func decodeMIDIChannelPrefix(d *decode.D) { d.FieldUintFn("delta", vlq) - d.FieldU8("status") - d.FieldU8("event") + d.FieldU16("metaevent", metaevents) d.FieldUintFn("channel", func(d *decode.D) uint64 { channel := uint64(0) data := vlf(d) @@ -214,8 +225,7 @@ func decodeMIDIChannelPrefix(d *decode.D) { func decodeMIDIPort(d *decode.D) { d.FieldUintFn("delta", vlq) - d.FieldU8("status") - d.FieldU8("event") + d.FieldU16("metaevent", metaevents) d.FieldUintFn("port", func(d *decode.D) uint64 { channel := uint64(0) data := vlf(d) @@ -231,9 +241,7 @@ func decodeMIDIPort(d *decode.D) { func decodeTempo(d *decode.D) { d.FieldUintFn("delta", vlq) - d.FieldU8("status") - d.FieldU8("event") - + d.FieldU16("metaevent", metaevents) d.FieldUintFn("tempo", func(d *decode.D) uint64 { tempo := uint64(0) data := vlf(d) @@ -249,9 +257,7 @@ func decodeTempo(d *decode.D) { func decodeSMPTEOffset(d *decode.D) { d.FieldUintFn("delta", vlq) - d.FieldU8("status") - d.FieldU8("event") - + d.FieldU16("metaevent", metaevents) d.FieldStruct("offset", func(d *decode.D) { var data []uint8 d.FieldStrFn("bytes", func(d *decode.D) string { @@ -305,8 +311,7 @@ func decodeSMPTEOffset(d *decode.D) { func decodeTimeSignature(d *decode.D) { d.FieldUintFn("delta", vlq) - d.FieldU8("status") - d.FieldU8("event") + d.FieldU16("metaevent", metaevents) d.FieldStruct("signature", func(d *decode.D) { var data []uint8 d.FieldStrFn("bytes", func(d *decode.D) string { @@ -342,9 +347,7 @@ func decodeTimeSignature(d *decode.D) { func decodeKeySignature(d *decode.D) { d.FieldUintFn("delta", vlq) - d.FieldU8("status") - d.FieldU8("event") - + d.FieldU16("metaevent", metaevents) d.FieldUintFn("key", func(d *decode.D) uint64 { data := vlf(d) key := uint64(data[0]) & 0x00ff @@ -358,8 +361,7 @@ func decodeKeySignature(d *decode.D) { func decodeEndOfTrack(d *decode.D) { d.FieldUintFn("delta", vlq) - d.FieldU8("status") - d.FieldU8("event") + d.FieldU16("metaevent", metaevents) d.FieldUintFn("length", func(d *decode.D) uint64 { return uint64(len(vlf(d))) }) @@ -367,9 +369,7 @@ func decodeEndOfTrack(d *decode.D) { func decodeSequencerSpecificEvent(d *decode.D) { d.FieldUintFn("delta", vlq) - d.FieldU8("status") - d.FieldU8("event") - + d.FieldU16("metaevent", metaevents) d.FieldStruct("info", func(d *decode.D) { var data []uint8 d.FieldStrFn("bytes", func(d *decode.D) string { diff --git a/format/midi/testdata/keys.fqtest b/format/midi/testdata/keys.fqtest index c4a421eb..9c9c05d0 100644 --- a/format/midi/testdata/keys.fqtest +++ b/format/midi/testdata/keys.fqtest @@ -15,178 +15,146 @@ $ ./fq -d midi d key-signatures.mid | | | events[0:34]: | | | [0]{}: TrackName 0x010| 00 | . | delta: 0 -0x010| ff | . | status: 255 -0x010| 03 | . | event: 3 +0x010| ff 03 | .. | metaevent: 3 (65283) 0x010| 0e 4b 65 79 20 53 69| .Key Si| name: "Key Signatures" 0x020|67 6e 61 74 75 72 65 73 |gnatures | | | | [1]{}: KeySignature 0x020| 00 | . | delta: 0 -0x020| ff | . | status: 255 -0x020| 59 | Y | event: 89 +0x020| ff 59 | .Y | metaevent: 89 (65369) 0x020| 02 00 00 | ... | key: "C major" (0) | | | [2]{}: KeySignature 0x020| 8f 00| ..| delta: 1920 -0x030|ff |. | status: 255 -0x030| 59 | Y | event: 89 +0x030|ff 59 |.Y | metaevent: 89 (65369) 0x030| 02 01 00 | ... | key: "G major" (256) | | | [3]{}: KeySignature 0x030| 8f 00 | .. | delta: 1920 -0x030| ff | . | status: 255 -0x030| 59 | Y | event: 89 +0x030| ff 59 | .Y | metaevent: 89 (65369) 0x030| 02 02 00 | ... | key: "D major" (512) | | | [4]{}: KeySignature 0x030| 8f 00 | .. | delta: 1920 -0x030| ff | . | status: 255 -0x030| 59| Y| event: 89 +0x030| ff 59| .Y| metaevent: 89 (65369) 0x040|02 03 00 |... | key: "A major" (768) | | | [5]{}: KeySignature 0x040| 8f 00 | .. | delta: 1920 -0x040| ff | . | status: 255 -0x040| 59 | Y | event: 89 +0x040| ff 59 | .Y | metaevent: 89 (65369) 0x040| 02 04 00 | ... | key: "E major" (1024) | | | [6]{}: KeySignature 0x040| 8f 00 | .. | delta: 1920 -0x040| ff | . | status: 255 -0x040| 59 | Y | event: 89 +0x040| ff 59 | .Y | metaevent: 89 (65369) 0x040| 02 05| ..| key: "B major" (1280) 0x050|00 |. | | | | [7]{}: KeySignature 0x050| 8f 00 | .. | delta: 1920 -0x050| ff | . | status: 255 -0x050| 59 | Y | event: 89 +0x050| ff 59 | .Y | metaevent: 89 (65369) 0x050| 02 06 00 | ... | key: "F♯ major" (1536) | | | [8]{}: KeySignature 0x050| 8f 00 | .. | delta: 1920 -0x050| ff | . | status: 255 -0x050| 59 | Y | event: 89 +0x050| ff 59 | .Y | metaevent: 89 (65369) 0x050| 02 07 00 | ... | key: "C♯ major" (1792) | | | [9]{}: KeySignature 0x050| 8f| .| delta: 1920 0x060|00 |. | -0x060| ff | . | status: 255 -0x060| 59 | Y | event: 89 +0x060| ff 59 | .Y | metaevent: 89 (65369) 0x060| 02 00 00 | ... | key: "C major" (0) | | | [10]{}: KeySignature 0x060| 8f 00 | .. | delta: 1920 -0x060| ff | . | status: 255 -0x060| 59 | Y | event: 89 +0x060| ff 59 | .Y | metaevent: 89 (65369) 0x060| 02 ff 00 | ... | key: "F major" (65280) | | | [11]{}: KeySignature 0x060| 8f 00 | .. | delta: 1920 -0x060| ff| .| status: 255 -0x070|59 |Y | event: 89 +0x060| ff| .| metaevent: 89 (65369) +0x070|59 |Y | 0x070| 02 fe 00 | ... | key: "B♭ major" (65024) | | | [12]{}: KeySignature 0x070| 8f 00 | .. | delta: 1920 -0x070| ff | . | status: 255 -0x070| 59 | Y | event: 89 +0x070| ff 59 | .Y | metaevent: 89 (65369) 0x070| 02 fd 00 | ... | key: "E♭ major" (64768) | | | [13]{}: KeySignature 0x070| 8f 00 | .. | delta: 1920 -0x070| ff | . | status: 255 -0x070| 59 | Y | event: 89 +0x070| ff 59 | .Y | metaevent: 89 (65369) 0x070| 02| .| key: "A♭ major" (64512) 0x080|fc 00 |.. | | | | [14]{}: KeySignature 0x080| 8f 00 | .. | delta: 1920 -0x080| ff | . | status: 255 -0x080| 59 | Y | event: 89 +0x080| ff 59 | .Y | metaevent: 89 (65369) 0x080| 02 fb 00 | ... | key: "D♭ major" (64256) | | | [15]{}: KeySignature 0x080| 8f 00 | .. | delta: 1920 -0x080| ff | . | status: 255 -0x080| 59 | Y | event: 89 +0x080| ff 59 | .Y | metaevent: 89 (65369) 0x080| 02 fa 00| ...| key: "G♭ major" (64000) | | | [16]{}: KeySignature 0x090|8f 00 |.. | delta: 1920 -0x090| ff | . | status: 255 -0x090| 59 | Y | event: 89 +0x090| ff 59 | .Y | metaevent: 89 (65369) 0x090| 02 f9 00 | ... | key: "C♭ major" (63744) | | | [17]{}: KeySignature 0x090| 8f 00 | .. | delta: 1920 -0x090| ff | . | status: 255 -0x090| 59 | Y | event: 89 +0x090| ff 59 | .Y | metaevent: 89 (65369) 0x090| 02 00 01 | ... | key: "A minor" (1) | | | [18]{}: KeySignature 0x090| 8f 00| ..| delta: 1920 -0x0a0|ff |. | status: 255 -0x0a0| 59 | Y | event: 89 +0x0a0|ff 59 |.Y | metaevent: 89 (65369) 0x0a0| 02 01 01 | ... | key: "E minor" (257) | | | [19]{}: KeySignature 0x0a0| 8f 00 | .. | delta: 1920 -0x0a0| ff | . | status: 255 -0x0a0| 59 | Y | event: 89 +0x0a0| ff 59 | .Y | metaevent: 89 (65369) 0x0a0| 02 02 01 | ... | key: "B minor" (513) | | | [20]{}: KeySignature 0x0a0| 8f 00 | .. | delta: 1920 -0x0a0| ff | . | status: 255 -0x0a0| 59| Y| event: 89 +0x0a0| ff 59| .Y| metaevent: 89 (65369) 0x0b0|02 03 01 |... | key: "F♯ minor" (769) | | | [21]{}: KeySignature 0x0b0| 8f 00 | .. | delta: 1920 -0x0b0| ff | . | status: 255 -0x0b0| 59 | Y | event: 89 +0x0b0| ff 59 | .Y | metaevent: 89 (65369) 0x0b0| 02 04 01 | ... | key: "C♯ minor" (1025) | | | [22]{}: KeySignature 0x0b0| 8f 00 | .. | delta: 1920 -0x0b0| ff | . | status: 255 -0x0b0| 59 | Y | event: 89 +0x0b0| ff 59 | .Y | metaevent: 89 (65369) 0x0b0| 02 05| ..| key: "G♯ minor" (1281) 0x0c0|01 |. | | | | [23]{}: KeySignature 0x0c0| 8f 00 | .. | delta: 1920 -0x0c0| ff | . | status: 255 -0x0c0| 59 | Y | event: 89 +0x0c0| ff 59 | .Y | metaevent: 89 (65369) 0x0c0| 02 06 01 | ... | key: "D♯ minor" (1537) | | | [24]{}: KeySignature 0x0c0| 8f 00 | .. | delta: 1920 -0x0c0| ff | . | status: 255 -0x0c0| 59 | Y | event: 89 +0x0c0| ff 59 | .Y | metaevent: 89 (65369) 0x0c0| 02 07 01 | ... | key: "A♯ minor" (1793) | | | [25]{}: KeySignature 0x0c0| 8f| .| delta: 1920 0x0d0|00 |. | -0x0d0| ff | . | status: 255 -0x0d0| 59 | Y | event: 89 +0x0d0| ff 59 | .Y | metaevent: 89 (65369) 0x0d0| 02 00 01 | ... | key: "A minor" (1) | | | [26]{}: KeySignature 0x0d0| 8f 00 | .. | delta: 1920 -0x0d0| ff | . | status: 255 -0x0d0| 59 | Y | event: 89 +0x0d0| ff 59 | .Y | metaevent: 89 (65369) 0x0d0| 02 ff 01 | ... | key: "D minor" (65281) | | | [27]{}: KeySignature 0x0d0| 9e 00 | .. | delta: 3840 -0x0d0| ff| .| status: 255 -0x0e0|59 |Y | event: 89 +0x0d0| ff| .| metaevent: 89 (65369) +0x0e0|59 |Y | 0x0e0| 02 fe 01 | ... | key: "G minor" (65025) | | | [28]{}: KeySignature 0x0e0| 8f 00 | .. | delta: 1920 -0x0e0| ff | . | status: 255 -0x0e0| 59 | Y | event: 89 +0x0e0| ff 59 | .Y | metaevent: 89 (65369) 0x0e0| 02 fd 01 | ... | key: "C minor" (64769) | | | [29]{}: KeySignature 0x0e0| 8f 00 | .. | delta: 1920 -0x0e0| ff | . | status: 255 -0x0e0| 59 | Y | event: 89 +0x0e0| ff 59 | .Y | metaevent: 89 (65369) 0x0e0| 02| .| key: "F minor" (64513) 0x0f0|fc 01 |.. | | | | [30]{}: KeySignature 0x0f0| 8f 00 | .. | delta: 1920 -0x0f0| ff | . | status: 255 -0x0f0| 59 | Y | event: 89 +0x0f0| ff 59 | .Y | metaevent: 89 (65369) 0x0f0| 02 fb 01 | ... | key: "B♭ minor" (64257) | | | [31]{}: KeySignature 0x0f0| 8f 00 | .. | delta: 1920 -0x0f0| ff | . | status: 255 -0x0f0| 59 | Y | event: 89 +0x0f0| ff 59 | .Y | metaevent: 89 (65369) 0x0f0| 02 fa 01| ...| key: "E♭ minor" (64001) | | | [32]{}: KeySignature 0x100|8f 00 |.. | delta: 1920 -0x100| ff | . | status: 255 -0x100| 59 | Y | event: 89 +0x100| ff 59 | .Y | metaevent: 89 (65369) 0x100| 02 f9 01 | ... | key: "A♭ minor" (63745) | | | [33]{}: EndOfTrack 0x100| 00 | . | delta: 0 -0x100| ff | . | status: 255 -0x100| 2f | / | event: 47 +0x100| ff 2f | ./ | metaevent: 47 (65327) 0x100| 00| | .| | length: 0 diff --git a/format/midi/testdata/test.fqtest b/format/midi/testdata/test.fqtest index 2a88c0d5..b0c40f5a 100644 --- a/format/midi/testdata/test.fqtest +++ b/format/midi/testdata/test.fqtest @@ -15,19 +15,16 @@ $ ./fq -d midi dv test.mid | | | events[0:4]: 0x16-0x36 (32) | | | [0]{}: TrackName 0x16-0x23 (13) 0x10| 00 | . | delta: 0 0x16-0x17 (1) -0x10| ff | . | status: 255 0x17-0x18 (1) -0x10| 03 | . | event: 3 0x18-0x19 (1) +0x10| ff 03 | .. | metaevent: 3 (65283) 0x17-0x19 (2) 0x10| 09 45 78 61 6d 70 6c| .Exampl| name: "Example 1" 0x19-0x23 (10) 0x20|65 20 31 |e 1 | | | | [1]{}: Tempo 0x23-0x2a (7) 0x20| 00 | . | delta: 0 0x23-0x24 (1) -0x20| ff | . | status: 255 0x24-0x25 (1) -0x20| 51 | Q | event: 81 0x25-0x26 (1) +0x20| ff 51 | .Q | metaevent: 81 (65361) 0x24-0x26 (2) 0x20| 03 07 a1 20 | ... | tempo: 500000 0x26-0x2a (4) | | | [2]{}: TimeSignature 0x2a-0x32 (8) 0x20| 00 | . | delta: 0 0x2a-0x2b (1) -0x20| ff | . | status: 255 0x2b-0x2c (1) -0x20| 58 | X | event: 88 0x2c-0x2d (1) +0x20| ff 58 | .X | metaevent: 88 (65368) 0x2b-0x2d (2) | | | signature{}: 0x2d-0x32 (5) 0x20| 04 04 02| ...| bytes: "[4 2 24 8]" 0x2d-0x32 (5) 0x30|18 08 |.. | @@ -37,8 +34,7 @@ $ ./fq -d midi dv test.mid | | | thirtySecondsPerQuarter: 8 | | | [3]{}: EndOfTrack 0x32-0x36 (4) 0x30| 00 | . | delta: 0 0x32-0x33 (1) -0x30| ff | . | status: 255 0x33-0x34 (1) -0x30| 2f | / | event: 47 0x34-0x35 (1) +0x30| ff 2f | ./ | metaevent: 47 (65327) 0x33-0x35 (2) 0x30| 00 | . | length: 0 0x35-0x36 (1) | | | [1]{}: track 0x36-0x8e (88) 0x30| 4d 54 72 6b | MTrk | tag: "MTrk" 0x36-0x3a (4) @@ -46,8 +42,8 @@ $ ./fq -d midi dv test.mid | | | events[0:15]: 0x3e-0x8e (80) | | | [0]{}: TrackName 0x3e-0x51 (19) 0x30| 00 | . | delta: 0 0x3e-0x3f (1) -0x30| ff| .| status: 255 0x3f-0x40 (1) -0x40|03 |. | event: 3 0x40-0x41 (1) +0x30| ff| .| metaevent: 3 (65283) 0x3f-0x41 (2) +0x40|03 |. | 0x40| 0f 41 63 6f 75 73 74 69 63 20 47 75 69 74 61| .Acoustic Guita| name: "Acoustic Guitar" 0x41-0x51 (16) 0x50|72 |r | | | | [1]{}: ProgramChange 0x51-0x54 (3) @@ -61,8 +57,7 @@ $ ./fq -d midi dv test.mid 0x50| 48 | H | velocity: 72 0x57-0x58 (1) | | | [3]{}: KeySignature 0x58-0x5e (6) 0x50| 00 | . | delta: 0 0x58-0x59 (1) -0x50| ff | . | status: 255 0x59-0x5a (1) -0x50| 59 | Y | event: 89 0x5a-0x5b (1) +0x50| ff 59 | .Y | metaevent: 89 (65369) 0x59-0x5b (2) 0x50| 02 00 01 | ... | key: "A minor" (1) 0x5b-0x5e (3) | | | [4]{}: Controller 0x5e-0x62 (4) 0x50| 00 | . | delta: 0 0x5e-0x5f (1) @@ -116,6 +111,5 @@ $ ./fq -d midi dv test.mid 0x80| 40 | @ | velocity: 64 0x89-0x8a (1) | | | [14]{}: EndOfTrack 0x8a-0x8e (4) 0x80| 00 | . | delta: 0 0x8a-0x8b (1) -0x80| ff | . | status: 255 0x8b-0x8c (1) -0x80| 2f | / | event: 47 0x8c-0x8d (1) +0x80| ff 2f | ./ | metaevent: 47 (65327) 0x8b-0x8d (2) 0x80| 00| | .| | length: 0 0x8d-0x8e (1)