diff --git a/format/midi/TODO.md b/format/midi/TODO.md index 0ad99f7b..89c05b1b 100644 --- a/format/midi/TODO.md +++ b/format/midi/TODO.md @@ -36,7 +36,7 @@ - [x] time signature - [x] sequencer specific event - [x] map manufacturer - - [ ] check key mappings + - [x] check key mappings - [ ] Combine status + event into metaevent field - midi events diff --git a/format/midi/keys.go b/format/midi/keys.go index d61c5851..cf643412 100644 --- a/format/midi/keys.go +++ b/format/midi/keys.go @@ -5,37 +5,37 @@ import ( ) const ( - keyCMajor = 0x0001 - keyGMajor = 0x0101 - keyDMajor = 0x0201 - keyAMajor = 0x0301 - keyEMajor = 0x0401 - keyBMajor = 0x0501 - keyFSharpMajor = 0x0601 - keyCSharpMajor = 0x0701 - keyFMajor = 0x0801 - keyBFlatMajor = 0x0901 - keyEFlatMajor = 0x0a01 - keyAFlatMajor = 0x0b01 - keyDFlatMajor = 0x0c01 - keyGFlatMajor = 0x0d01 - keyCFlatMajor = 0x0e01 + keyCMajor = 0x0000 + keyGMajor = 0x0100 + keyDMajor = 0x0200 + keyAMajor = 0x0300 + keyEMajor = 0x0400 + keyBMajor = 0x0500 + keyFSharpMajor = 0x0600 + keyCSharpMajor = 0x0700 + keyFMajor = 0xff00 + keyBFlatMajor = 0xfe00 + keyEFlatMajor = 0xfd00 + keyAFlatMajor = 0xfc00 + keyDFlatMajor = 0xfb00 + keyGFlatMajor = 0xfa00 + keyCFlatMajor = 0xf900 - keyAMinor = 0x0000 - keyEMinor = 0x0100 - keyBMinor = 0x0200 - keyASharpMinor = 0x0300 - keyDSharpMinor = 0x0400 - keyGSharpMinor = 0x0500 - keyCSharpMinor = 0x0600 - keyFSharpMinor = 0x0700 - keyDMinor = 0x0800 - keyGMinor = 0x0900 - keyCMinor = 0x0a00 - keyFMinor = 0x0b00 - keyBFlatMinor = 0x0c00 - keyEFlatMinor = 0x0d00 - keyAFlatMinor = 0x0e00 + keyAMinor = 0x0001 + keyEMinor = 0x0101 + keyBMinor = 0x0201 + keyFSharpMinor = 0x0301 + keyCSharpMinor = 0x0401 + keyGSharpMinor = 0x0501 + keyDSharpMinor = 0x0601 + keyASharpMinor = 0x0701 + keyDMinor = 0xff01 + keyGMinor = 0xfe01 + keyCMinor = 0xfd01 + keyFMinor = 0xfc01 + keyBFlatMinor = 0xfb01 + keyEFlatMinor = 0xfa01 + keyAFlatMinor = 0xf901 ) var keys = scalar.UintMapSymStr{ @@ -58,11 +58,11 @@ var keys = scalar.UintMapSymStr{ keyAMinor: "A minor", keyEMinor: "E minor", keyBMinor: "B minor", - keyASharpMinor: "A♯ minor", - keyDSharpMinor: "D♯ minor", - keyGSharpMinor: "G♯ minor", - keyCSharpMinor: "C♯ minor", keyFSharpMinor: "F♯ minor", + keyCSharpMinor: "C♯ minor", + keyGSharpMinor: "G♯ minor", + keyDSharpMinor: "D♯ minor", + keyASharpMinor: "A♯ minor", keyDMinor: "D minor", keyGMinor: "G minor", keyCMinor: "C minor", diff --git a/format/midi/metaevents.go b/format/midi/metaevents.go index d04e41f3..2bba5d83 100644 --- a/format/midi/metaevents.go +++ b/format/midi/metaevents.go @@ -331,13 +331,15 @@ func decodeKeySignature(d *decode.D) { d.FieldU8("status") d.FieldU8("event") - data := vlf(d) - if len(data) > 1 { - key := (uint64(data[0]) << 8) & 0xff00 - key |= (uint64(data[1]) << 0) & 0x00ff + d.FieldUintFn("key", func (d *decode.D) uint64 { + data := vlf(d) + key := uint64(data[0]) & 0x00ff + key <<= 8 + key |= uint64(data[1]) & 0x00ff - d.FieldValueUint("key", key, keys) - } + return key + + },keys) } func decodeEndOfTrack(d *decode.D) { diff --git a/format/midi/testdata/key-signatures.mid b/format/midi/testdata/key-signatures.mid new file mode 100644 index 00000000..97f4d535 Binary files /dev/null and b/format/midi/testdata/key-signatures.mid differ diff --git a/format/midi/testdata/keys.fqtest b/format/midi/testdata/keys.fqtest new file mode 100644 index 00000000..d1a6af32 --- /dev/null +++ b/format/midi/testdata/keys.fqtest @@ -0,0 +1,192 @@ +$ ./fq -d midi d key-signatures.mid + |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: key-signatures.mid (midi) + | | | header{}: + | | | header[0:5]: +0x000|4d 54 68 64 |MThd | [0]: "MThd" +0x000| 00 00 00 06 | .... | [1]: 6 +0x000| 00 00 | .. | [2]: 0 +0x000| 00 01 | .. | [3]: 1 +0x000| 01 e0 | .. | [4]: 480 + | | | tracks[0:1]: + | | | [0]{}: track +0x000| 4d 54| MT| tag: "MTrk" +0x010|72 6b |rk | +0x010| 00 00 00 f5 | .... | length: 245 + | | | events[0:34]: + | | | [0]{}: TrackName +0x010| 00 | . | delta: 0 +0x010| ff | . | status: 255 +0x010| 03 | . | event: 3 +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| 02 00 00 | ... | key: "C major" (0) + | | | [2]{}: KeySignature +0x020| 8f 00| ..| delta: 1920 +0x030|ff |. | status: 255 +0x030| 59 | Y | event: 89 +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| 02 02 00 | ... | key: "D major" (512) + | | | [4]{}: KeySignature +0x030| 8f 00 | .. | delta: 1920 +0x030| ff | . | status: 255 +0x030| 59| Y| event: 89 +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| 02 04 00 | ... | key: "E major" (1024) + | | | [6]{}: KeySignature +0x040| 8f 00 | .. | delta: 1920 +0x040| ff | . | status: 255 +0x040| 59 | Y | event: 89 +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| 02 06 00 | ... | key: "F♯ major" (1536) + | | | [8]{}: KeySignature +0x050| 8f 00 | .. | delta: 1920 +0x050| ff | . | status: 255 +0x050| 59 | Y | event: 89 +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| 02 00 00 | ... | key: "C major" (0) + | | | [10]{}: KeySignature +0x060| 8f 00 | .. | delta: 1920 +0x060| ff | . | status: 255 +0x060| 59 | Y | event: 89 +0x060| 02 ff 00 | ... | key: "F major" (65280) + | | | [11]{}: KeySignature +0x060| 8f 00 | .. | delta: 1920 +0x060| ff| .| status: 255 +0x070|59 |Y | event: 89 +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| 02 fd 00 | ... | key: "E♭ major" (64768) + | | | [13]{}: KeySignature +0x070| 8f 00 | .. | delta: 1920 +0x070| ff | . | status: 255 +0x070| 59 | Y | event: 89 +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| 02 fb 00 | ... | key: "D♭ major" (64256) + | | | [15]{}: KeySignature +0x080| 8f 00 | .. | delta: 1920 +0x080| ff | . | status: 255 +0x080| 59 | Y | event: 89 +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| 02 f9 00 | ... | key: "C♭ major" (63744) + | | | [17]{}: KeySignature +0x090| 8f 00 | .. | delta: 1920 +0x090| ff | . | status: 255 +0x090| 59 | Y | event: 89 +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| 02 01 01 | ... | key: "E minor" (257) + | | | [19]{}: KeySignature +0x0a0| 8f 00 | .. | delta: 1920 +0x0a0| ff | . | status: 255 +0x0a0| 59 | Y | event: 89 +0x0a0| 02 02 01 | ... | key: "B minor" (513) + | | | [20]{}: KeySignature +0x0a0| 8f 00 | .. | delta: 1920 +0x0a0| ff | . | status: 255 +0x0a0| 59| Y| event: 89 +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| 02 04 01 | ... | key: "C♯ minor" (1025) + | | | [22]{}: KeySignature +0x0b0| 8f 00 | .. | delta: 1920 +0x0b0| ff | . | status: 255 +0x0b0| 59 | Y | event: 89 +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| 02 06 01 | ... | key: "D♯ minor" (1537) + | | | [24]{}: KeySignature +0x0c0| 8f 00 | .. | delta: 1920 +0x0c0| ff | . | status: 255 +0x0c0| 59 | Y | event: 89 +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| 02 00 01 | ... | key: "A minor" (1) + | | | [26]{}: KeySignature +0x0d0| 8f 00 | .. | delta: 1920 +0x0d0| ff | . | status: 255 +0x0d0| 59 | Y | event: 89 +0x0d0| 02 ff 01 | ... | key: "D minor" (65281) + | | | [27]{}: KeySignature +0x0d0| 9e 00 | .. | delta: 3840 +0x0d0| ff| .| status: 255 +0x0e0|59 |Y | event: 89 +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| 02 fd 01 | ... | key: "C minor" (64769) + | | | [29]{}: KeySignature +0x0e0| 8f 00 | .. | delta: 1920 +0x0e0| ff | . | status: 255 +0x0e0| 59 | Y | event: 89 +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| 02 fb 01 | ... | key: "B♭ minor" (64257) + | | | [31]{}: KeySignature +0x0f0| 8f 00 | .. | delta: 1920 +0x0f0| ff | . | status: 255 +0x0f0| 59 | Y | event: 89 +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| 02 f9 01 | ... | key: "A♭ minor" (63745) + | | | [33]{}: EndOfTrack +0x100| 00 | . | delta: 0 +0x100| ff | . | status: 255 +0x100| 2f | / | event: 47 +0x100| 00| | .| | gap0: raw bits diff --git a/format/midi/testdata/test.fqtest b/format/midi/testdata/test.fqtest index 91029162..120a9fde 100644 --- a/format/midi/testdata/test.fqtest +++ b/format/midi/testdata/test.fqtest @@ -56,11 +56,11 @@ $ ./fq -d midi dv test.mid 0x50| 90 | . | channel: 0 0x55-0x56 (1) 0x50| 30 | 0 | note: "C3" (48) 0x56-0x57 (1) 0x50| 48 | H | velocity: 72 0x57-0x58 (1) - | | | [3]{}: KeySignature 0x58-0x5b (3) + | | | [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) - | | | key: "C major" (1) +0x50| 02 00 01 | ... | key: "A minor" (1) 0x5b-0x5e (3) | | | [4]{}: Controller 0x5e-0x62 (4) 0x50| 00 | . | delta: 0 0x5e-0x5f (1) 0x50| b0| .| channel: 0 0x5f-0x60 (1) @@ -118,5 +118,4 @@ $ ./fq -d midi dv test.mid 0x20| 04 04 02| ...| gap0: raw bits 0x2d-0x32 (5) 0x30|18 08 |.. | 0x30| 00 | . | gap1: raw bits 0x35-0x36 (1) -0x50| 02 00 01 | ... | gap2: raw bits 0x5b-0x5e (3) -0x80| 00| | .| | gap3: raw bits 0x8d-0x8e (1) +0x80| 00| | .| | gap2: raw bits 0x8d-0x8e (1)